• 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  * Class loading, including bootstrap class loader, linking, and
19  * initialization.
20  */
21 
22 #define LOG_CLASS_LOADING 0
23 
24 #include "Dalvik.h"
25 #include "libdex/DexClass.h"
26 
27 #include <stdlib.h>
28 #include <stddef.h>
29 #include <sys/stat.h>
30 
31 #if LOG_CLASS_LOADING
32 #include <unistd.h>
33 #include <pthread.h>
34 #include <cutils/process_name.h>
35 #include <sys/types.h>
36 #endif
37 
38 /*
39 Notes on Linking and Verification
40 
41 The basic way to retrieve a class is to load it, make sure its superclass
42 and interfaces are available, prepare its fields, and return it.  This gets
43 a little more complicated when multiple threads can be trying to retrieve
44 the class simultaneously, requiring that we use the class object's monitor
45 to keep things orderly.
46 
47 The linking (preparing, resolving) of a class can cause us to recursively
48 load superclasses and interfaces.  Barring circular references (e.g. two
49 classes that are superclasses of each other), this will complete without
50 the loader attempting to access the partially-linked class.
51 
52 With verification, the situation is different.  If we try to verify
53 every class as we load it, we quickly run into trouble.  Even the lowly
54 java.lang.Object requires CloneNotSupportedException; follow the list
55 of referenced classes and you can head down quite a trail.  The trail
56 eventually leads back to Object, which is officially not fully-formed yet.
57 
58 The VM spec (specifically, v2 5.4.1) notes that classes pulled in during
59 verification do not need to be prepared or verified.  This means that we
60 are allowed to have loaded but unverified classes.  It further notes that
61 the class must be verified before it is initialized, which allows us to
62 defer verification for all classes until class init.  You can't execute
63 code or access fields in an uninitialized class, so this is safe.
64 
65 It also allows a more peaceful coexistence between verified and
66 unverifiable code.  If class A refers to B, and B has a method that
67 refers to a bogus class C, should we allow class A to be verified?
68 If A only exercises parts of B that don't use class C, then there is
69 nothing wrong with running code in A.  We can fully verify both A and B,
70 and allow execution to continue until B causes initialization of C.  The
71 VerifyError is thrown close to the point of use.
72 
73 This gets a little weird with java.lang.Class, which is the only class
74 that can be instantiated before it is initialized.  We have to force
75 initialization right after the class is created, because by definition we
76 have instances of it on the heap, and somebody might get a class object and
77 start making virtual calls on it.  We can end up going recursive during
78 verification of java.lang.Class, but we avoid that by checking to see if
79 verification is already in progress before we try to initialize it.
80 */
81 
82 /*
83 Notes on class loaders and interaction with optimization / verification
84 
85 In what follows, "pre-verification" and "optimization" are the steps
86 performed by the dexopt command, which attempts to verify and optimize
87 classes as part of unpacking jar files and storing the DEX data in the
88 dalvik-cache directory.  These steps are performed by loading the DEX
89 files directly, without any assistance from ClassLoader instances.
90 
91 When we pre-verify and optimize a class in a DEX file, we make some
92 assumptions about where the class loader will go to look for classes.
93 If we can't guarantee those assumptions, e.g. because a class ("AppClass")
94 references something not defined in the bootstrap jars or the AppClass jar,
95 we can't pre-verify or optimize the class.
96 
97 The VM doesn't define the behavior of user-defined class loaders.
98 For example, suppose application class AppClass, loaded by UserLoader,
99 has a method that creates a java.lang.String.  The first time
100 AppClass.stringyMethod tries to do something with java.lang.String, it
101 asks UserLoader to find it.  UserLoader is expected to defer to its parent
102 loader, but isn't required to.  UserLoader might provide a replacement
103 for String.
104 
105 We can run into trouble if we pre-verify AppClass with the assumption that
106 java.lang.String will come from core.jar, and don't verify this assumption
107 at runtime.  There are two places that an alternate implementation of
108 java.lang.String can come from: the AppClass jar, or from some other jar
109 that UserLoader knows about.  (Someday UserLoader will be able to generate
110 some bytecode and call DefineClass, but not yet.)
111 
112 To handle the first situation, the pre-verifier will explicitly check for
113 conflicts between the class being optimized/verified and the bootstrap
114 classes.  If an app jar contains a class that has the same package and
115 class name as a class in a bootstrap jar, the verification resolver refuses
116 to find either, which will block pre-verification and optimization on
117 classes that reference ambiguity.  The VM will postpone verification of
118 the app class until first load.
119 
120 For the second situation, we need to ensure that all references from a
121 pre-verified class are satisified by the class' jar or earlier bootstrap
122 jars.  In concrete terms: when resolving a reference to NewClass,
123 which was caused by a reference in class AppClass, we check to see if
124 AppClass was pre-verified.  If so, we require that NewClass comes out
125 of either the AppClass jar or one of the jars in the bootstrap path.
126 (We may not control the class loaders, but we do manage the DEX files.
127 We can verify that it's either (loader==null && dexFile==a_boot_dex)
128 or (loader==UserLoader && dexFile==AppClass.dexFile).  Classes from
129 DefineClass can't be pre-verified, so this doesn't apply.)
130 
131 This should ensure that you can't "fake out" the pre-verifier by creating
132 a user-defined class loader that replaces system classes.  It should
133 also ensure that you can write such a loader and have it work in the
134 expected fashion; all you lose is some performance due to "just-in-time
135 verification" and the lack of DEX optimizations.
136 
137 There is a "back door" of sorts in the class resolution check, due to
138 the fact that the "class ref" entries are shared between the bytecode
139 and meta-data references (e.g. annotations and exception handler lists).
140 The class references in annotations have no bearing on class verification,
141 so when a class does an annotation query that causes a class reference
142 index to be resolved, we don't want to fail just because the calling
143 class was pre-verified and the resolved class is in some random DEX file.
144 The successful resolution adds the class to the "resolved classes" table,
145 so when optimized bytecode references it we don't repeat the resolve-time
146 check.  We can avoid this by not updating the "resolved classes" table
147 when the class reference doesn't come out of something that has been
148 checked by the verifier, but that has a nonzero performance impact.
149 Since the ultimate goal of this test is to catch an unusual situation
150 (user-defined class loaders redefining core classes), the added caution
151 may not be worth the performance hit.
152 */
153 
154 /*
155  * Class serial numbers start at this value.  We use a nonzero initial
156  * value so they stand out in binary dumps (e.g. hprof output).
157  */
158 #define INITIAL_CLASS_SERIAL_NUMBER 0x50000000
159 
160 /*
161  * Constant used to size an auxillary class object data structure.
162  * For optimum memory use this should be equal to or slightly larger than
163  * the number of classes loaded when the zygote finishes initializing.
164  */
165 #define ZYGOTE_CLASS_CUTOFF 2304
166 
167 static ClassPathEntry* processClassPath(const char* pathStr, bool isBootstrap);
168 static void freeCpeArray(ClassPathEntry* cpe);
169 
170 static ClassObject* findClassFromLoaderNoInit(
171     const char* descriptor, Object* loader);
172 static ClassObject* findClassNoInit(const char* descriptor, Object* loader,\
173     DvmDex* pDvmDex);
174 static ClassObject* loadClassFromDex(DvmDex* pDvmDex,
175     const DexClassDef* pClassDef, Object* loader);
176 static void loadMethodFromDex(ClassObject* clazz, const DexMethod* pDexMethod,\
177     Method* meth);
178 static int computeJniArgInfo(const DexProto* proto);
179 static void loadSFieldFromDex(ClassObject* clazz,
180     const DexField* pDexSField, StaticField* sfield);
181 static void loadIFieldFromDex(ClassObject* clazz,
182     const DexField* pDexIField, InstField* field);
183 static void freeMethodInnards(Method* meth);
184 static bool createVtable(ClassObject* clazz);
185 static bool createIftable(ClassObject* clazz);
186 static bool insertMethodStubs(ClassObject* clazz);
187 static bool computeFieldOffsets(ClassObject* clazz);
188 static void throwEarlierClassFailure(ClassObject* clazz);
189 
190 #if LOG_CLASS_LOADING
191 /*
192  * Logs information about a class loading with given timestamp.
193  *
194  * TODO: In the case where we fail in dvmLinkClass() and log the class as closing (type='<'),
195  * it would probably be better to use a new type code to indicate the failure.  This change would
196  * require a matching change in the parser and analysis code in frameworks/base/tools/preload.
197  */
logClassLoadWithTime(char type,ClassObject * clazz,u8 time)198 static void logClassLoadWithTime(char type, ClassObject* clazz, u8 time) {
199     pid_t ppid = getppid();
200     pid_t pid = getpid();
201     unsigned int tid = (unsigned int) pthread_self();
202 
203     LOG(LOG_INFO, "PRELOAD", "%c%d:%d:%d:%s:%d:%s:%lld\n", type, ppid, pid, tid,
204         get_process_name(), (int) clazz->classLoader, clazz->descriptor,
205         time);
206 }
207 
208 /*
209  * Logs information about a class loading.
210  */
logClassLoad(char type,ClassObject * clazz)211 static void logClassLoad(char type, ClassObject* clazz) {
212     logClassLoadWithTime(type, clazz, dvmGetThreadCpuTimeNsec());
213 }
214 #endif
215 
216 /*
217  * Some LinearAlloc unit tests.
218  */
linearAllocTests()219 static void linearAllocTests()
220 {
221     char* fiddle;
222     int try = 1;
223 
224     switch (try) {
225     case 0:
226         fiddle = dvmLinearAlloc(NULL, 3200-28);
227         dvmLinearReadOnly(NULL, fiddle);
228         break;
229     case 1:
230         fiddle = dvmLinearAlloc(NULL, 3200-24);
231         dvmLinearReadOnly(NULL, fiddle);
232         break;
233     case 2:
234         fiddle = dvmLinearAlloc(NULL, 3200-20);
235         dvmLinearReadOnly(NULL, fiddle);
236         break;
237     case 3:
238         fiddle = dvmLinearAlloc(NULL, 3200-16);
239         dvmLinearReadOnly(NULL, fiddle);
240         break;
241     case 4:
242         fiddle = dvmLinearAlloc(NULL, 3200-12);
243         dvmLinearReadOnly(NULL, fiddle);
244         break;
245     }
246     fiddle = dvmLinearAlloc(NULL, 896);
247     dvmLinearReadOnly(NULL, fiddle);
248     fiddle = dvmLinearAlloc(NULL, 20);      // watch addr of this alloc
249     dvmLinearReadOnly(NULL, fiddle);
250 
251     fiddle = dvmLinearAlloc(NULL, 1);
252     fiddle[0] = 'q';
253     dvmLinearReadOnly(NULL, fiddle);
254     fiddle = dvmLinearAlloc(NULL, 4096);
255     fiddle[0] = 'x';
256     fiddle[4095] = 'y';
257     dvmLinearReadOnly(NULL, fiddle);
258     dvmLinearFree(NULL, fiddle);
259     fiddle = dvmLinearAlloc(NULL, 0);
260     dvmLinearReadOnly(NULL, fiddle);
261     fiddle = dvmLinearRealloc(NULL, fiddle, 12);
262     fiddle[11] = 'z';
263     dvmLinearReadOnly(NULL, fiddle);
264     fiddle = dvmLinearRealloc(NULL, fiddle, 5);
265     dvmLinearReadOnly(NULL, fiddle);
266     fiddle = dvmLinearAlloc(NULL, 17001);
267     fiddle[0] = 'x';
268     fiddle[17000] = 'y';
269     dvmLinearReadOnly(NULL, fiddle);
270 
271     char* str = dvmLinearStrdup(NULL, "This is a test!");
272     LOGI("GOT: '%s'\n", str);
273 
274     /* try to check the bounds; allocator may round allocation size up */
275     fiddle = dvmLinearAlloc(NULL, 12);
276     LOGI("Should be 1: %d\n", dvmLinearAllocContains(fiddle, 12));
277     LOGI("Should be 0: %d\n", dvmLinearAllocContains(fiddle, 13));
278     LOGI("Should be 0: %d\n", dvmLinearAllocContains(fiddle - 128*1024, 1));
279 
280     dvmLinearAllocDump(NULL);
281     dvmLinearFree(NULL, str);
282 }
283 
284 /*
285  * Initialize the bootstrap class loader.
286  *
287  * Call this after the bootclasspath string has been finalized.
288  */
dvmClassStartup(void)289 bool dvmClassStartup(void)
290 {
291     ClassObject* unlinkedClass;
292 
293     /* make this a requirement -- don't currently support dirs in path */
294     if (strcmp(gDvm.bootClassPathStr, ".") == 0) {
295         LOGE("ERROR: must specify non-'.' bootclasspath\n");
296         return false;
297     }
298 
299     gDvm.loadedClasses =
300         dvmHashTableCreate(256, (HashFreeFunc) dvmFreeClassInnards);
301 
302     gDvm.pBootLoaderAlloc = dvmLinearAllocCreate(NULL);
303     if (gDvm.pBootLoaderAlloc == NULL)
304         return false;
305 
306     if (false) {
307         linearAllocTests();
308         exit(0);
309     }
310 
311     /*
312      * Class serial number.  We start with a high value to make it distinct
313      * in binary dumps (e.g. hprof).
314      */
315     gDvm.classSerialNumber = INITIAL_CLASS_SERIAL_NUMBER;
316 
317     /* Set up the table we'll use for tracking initiating loaders for
318      * early classes.
319      * If it's NULL, we just fall back to the InitiatingLoaderList in the
320      * ClassObject, so it's not fatal to fail this allocation.
321      */
322     gDvm.initiatingLoaderList =
323         calloc(ZYGOTE_CLASS_CUTOFF, sizeof(InitiatingLoaderList));
324 
325     /* This placeholder class is used while a ClassObject is
326      * loading/linking so those not in the know can still say
327      * "obj->clazz->...".
328      */
329     unlinkedClass = &gDvm.unlinkedJavaLangClassObject;
330 
331     memset(unlinkedClass, 0, sizeof(*unlinkedClass));
332 
333     /* Set obj->clazz to NULL so anyone who gets too interested
334      * in the fake class will crash.
335      */
336     DVM_OBJECT_INIT(&unlinkedClass->obj, NULL);
337     unlinkedClass->descriptor = "!unlinkedClass";
338     dvmSetClassSerialNumber(unlinkedClass);
339 
340     gDvm.unlinkedJavaLangClass = unlinkedClass;
341 
342     /*
343      * Process the bootstrap class path.  This means opening the specified
344      * DEX or Jar files and possibly running them through the optimizer.
345      */
346     assert(gDvm.bootClassPath == NULL);
347     processClassPath(gDvm.bootClassPathStr, true);
348 
349     if (gDvm.bootClassPath == NULL)
350         return false;
351 
352     return true;
353 }
354 
355 /*
356  * Clean up.
357  */
dvmClassShutdown(void)358 void dvmClassShutdown(void)
359 {
360     int i;
361 
362     /* discard all system-loaded classes */
363     dvmHashTableFree(gDvm.loadedClasses);
364     gDvm.loadedClasses = NULL;
365 
366     /* discard primitive classes created for arrays */
367     for (i = 0; i < PRIM_MAX; i++)
368         dvmFreeClassInnards(gDvm.primitiveClass[i]);
369 
370     /* this closes DEX files, JAR files, etc. */
371     freeCpeArray(gDvm.bootClassPath);
372     gDvm.bootClassPath = NULL;
373 
374     dvmLinearAllocDestroy(NULL);
375 
376     free(gDvm.initiatingLoaderList);
377 }
378 
379 
380 /*
381  * ===========================================================================
382  *      Bootstrap class loader
383  * ===========================================================================
384  */
385 
386 /*
387  * Dump the contents of a ClassPathEntry array.
388  */
dumpClassPath(const ClassPathEntry * cpe)389 static void dumpClassPath(const ClassPathEntry* cpe)
390 {
391     int idx = 0;
392 
393     while (cpe->kind != kCpeLastEntry) {
394         const char* kindStr;
395 
396         switch (cpe->kind) {
397         case kCpeDir:       kindStr = "dir";    break;
398         case kCpeJar:       kindStr = "jar";    break;
399         case kCpeDex:       kindStr = "dex";    break;
400         default:            kindStr = "???";    break;
401         }
402 
403         LOGI("  %2d: type=%s %s %p\n", idx, kindStr, cpe->fileName, cpe->ptr);
404         if (CALC_CACHE_STATS && cpe->kind == kCpeJar) {
405             JarFile* pJarFile = (JarFile*) cpe->ptr;
406             DvmDex* pDvmDex = dvmGetJarFileDex(pJarFile);
407             dvmDumpAtomicCacheStats(pDvmDex->pInterfaceCache);
408         }
409 
410         cpe++;
411         idx++;
412     }
413 }
414 
415 /*
416  * Dump the contents of the bootstrap class path.
417  */
dvmDumpBootClassPath(void)418 void dvmDumpBootClassPath(void)
419 {
420     dumpClassPath(gDvm.bootClassPath);
421 }
422 
423 /*
424  * Returns "true" if the class path contains the specified path.
425  */
dvmClassPathContains(const ClassPathEntry * cpe,const char * path)426 bool dvmClassPathContains(const ClassPathEntry* cpe, const char* path)
427 {
428     while (cpe->kind != kCpeLastEntry) {
429         if (strcmp(cpe->fileName, path) == 0)
430             return true;
431 
432         cpe++;
433     }
434     return false;
435 }
436 
437 /*
438  * Free an array of ClassPathEntry structs.
439  *
440  * We release the contents of each entry, then free the array itself.
441  */
freeCpeArray(ClassPathEntry * cpe)442 static void freeCpeArray(ClassPathEntry* cpe)
443 {
444     ClassPathEntry* cpeStart = cpe;
445 
446     if (cpe == NULL)
447         return;
448 
449     while (cpe->kind != kCpeLastEntry) {
450         switch (cpe->kind) {
451         case kCpeJar:
452             /* free JarFile */
453             dvmJarFileFree((JarFile*) cpe->ptr);
454             break;
455         case kCpeDex:
456             /* free RawDexFile */
457             dvmRawDexFileFree((RawDexFile*) cpe->ptr);
458             break;
459         default:
460             /* e.g. kCpeDir */
461             assert(cpe->ptr == NULL);
462             break;
463         }
464 
465         free(cpe->fileName);
466         cpe++;
467     }
468 
469     free(cpeStart);
470 }
471 
472 /*
473  * Prepare a ClassPathEntry struct, which at this point only has a valid
474  * filename.  We need to figure out what kind of file it is, and for
475  * everything other than directories we need to open it up and see
476  * what's inside.
477  */
prepareCpe(ClassPathEntry * cpe,bool isBootstrap)478 static bool prepareCpe(ClassPathEntry* cpe, bool isBootstrap)
479 {
480     JarFile* pJarFile = NULL;
481     RawDexFile* pRawDexFile = NULL;
482     struct stat sb;
483     int cc;
484 
485     cc = stat(cpe->fileName, &sb);
486     if (cc < 0) {
487         LOGD("Unable to stat classpath element '%s'\n", cpe->fileName);
488         return false;
489     }
490     if (S_ISDIR(sb.st_mode)) {
491         /*
492          * The directory will usually have .class files in subdirectories,
493          * which may be a few levels down.  Doing a recursive scan and
494          * caching the results would help us avoid hitting the filesystem
495          * on misses.  Whether or not this is of measureable benefit
496          * depends on a number of factors, but most likely it is not
497          * worth the effort (especially since most of our stuff will be
498          * in DEX or JAR).
499          */
500         cpe->kind = kCpeDir;
501         assert(cpe->ptr == NULL);
502         return true;
503     }
504 
505     if (dvmJarFileOpen(cpe->fileName, NULL, &pJarFile, isBootstrap) == 0) {
506         cpe->kind = kCpeJar;
507         cpe->ptr = pJarFile;
508         return true;
509     }
510 
511     // TODO: do we still want to support "raw" DEX files in the classpath?
512     if (dvmRawDexFileOpen(cpe->fileName, NULL, &pRawDexFile, isBootstrap) == 0)
513     {
514         cpe->kind = kCpeDex;
515         cpe->ptr = pRawDexFile;
516         return true;
517     }
518 
519     LOGD("Unable to process classpath element '%s'\n", cpe->fileName);
520     return false;
521 }
522 
523 /*
524  * Convert a colon-separated list of directories, Zip files, and DEX files
525  * into an array of ClassPathEntry structs.
526  *
527  * During normal startup we fail if there are no entries, because we won't
528  * get very far without the basic language support classes, but if we're
529  * optimizing a DEX file we allow it.
530  *
531  * If entries are added or removed from the bootstrap class path, the
532  * dependencies in the DEX files will break, and everything except the
533  * very first entry will need to be regenerated.
534  */
processClassPath(const char * pathStr,bool isBootstrap)535 static ClassPathEntry* processClassPath(const char* pathStr, bool isBootstrap)
536 {
537     ClassPathEntry* cpe = NULL;
538     char* mangle;
539     char* cp;
540     const char* end;
541     int idx, count;
542 
543     assert(pathStr != NULL);
544 
545     mangle = strdup(pathStr);
546 
547     /*
548      * Run through and essentially strtok() the string.  Get a count of
549      * the #of elements while we're at it.
550      *
551      * If the path was constructed strangely (e.g. ":foo::bar:") this will
552      * over-allocate, which isn't ideal but is mostly harmless.
553      */
554     count = 1;
555     for (cp = mangle; *cp != '\0'; cp++) {
556         if (*cp == ':') {   /* separates two entries */
557             count++;
558             *cp = '\0';
559         }
560     }
561     end = cp;
562 
563     /*
564      * Allocate storage.  We over-alloc by one so we can set an "end" marker.
565      */
566     cpe = (ClassPathEntry*) calloc(count+1, sizeof(ClassPathEntry));
567 
568     /*
569      * Set the global pointer so the DEX file dependency stuff can find it.
570      */
571     gDvm.bootClassPath = cpe;
572 
573     /*
574      * Go through a second time, pulling stuff out.
575      */
576     cp = mangle;
577     idx = 0;
578     while (cp < end) {
579         if (*cp == '\0') {
580             /* leading, trailing, or doubled ':'; ignore it */
581         } else {
582             ClassPathEntry tmp;
583             tmp.kind = kCpeUnknown;
584             tmp.fileName = strdup(cp);
585             tmp.ptr = NULL;
586 
587             /* drop an end marker here so DEX loader can walk unfinished list */
588             cpe[idx].kind = kCpeLastEntry;
589             cpe[idx].fileName = NULL;
590             cpe[idx].ptr = NULL;
591 
592             if (!prepareCpe(&tmp, isBootstrap)) {
593                 /* drop from list and continue on */
594                 free(tmp.fileName);
595             } else {
596                 /* copy over, pointers and all */
597                 if (tmp.fileName[0] != '/')
598                     LOGW("Non-absolute bootclasspath entry '%s'\n",
599                         tmp.fileName);
600                 cpe[idx] = tmp;
601                 idx++;
602             }
603         }
604 
605         cp += strlen(cp) +1;
606     }
607     assert(idx <= count);
608     if (idx == 0 && !gDvm.optimizing) {
609         LOGE("ERROR: no valid entries found in bootclasspath '%s'\n", pathStr);
610         free(cpe);
611         cpe = NULL;
612         goto bail;
613     }
614 
615     LOGVV("  (filled %d of %d slots)\n", idx, count);
616 
617     /* put end marker in over-alloc slot */
618     cpe[idx].kind = kCpeLastEntry;
619     cpe[idx].fileName = NULL;
620     cpe[idx].ptr = NULL;
621 
622     //dumpClassPath(cpe);
623 
624 bail:
625     free(mangle);
626     gDvm.bootClassPath = cpe;
627     return cpe;
628 }
629 
630 /*
631  * Search the DEX files we loaded from the bootstrap class path for a DEX
632  * file that has the class with the matching descriptor.
633  *
634  * Returns the matching DEX file and DexClassDef entry if found, otherwise
635  * returns NULL.
636  */
searchBootPathForClass(const char * descriptor,const DexClassDef ** ppClassDef)637 static DvmDex* searchBootPathForClass(const char* descriptor,
638     const DexClassDef** ppClassDef)
639 {
640     const ClassPathEntry* cpe = gDvm.bootClassPath;
641     const DexClassDef* pFoundDef = NULL;
642     DvmDex* pFoundFile = NULL;
643 
644     LOGVV("+++ class '%s' not yet loaded, scanning bootclasspath...\n",
645         descriptor);
646 
647     while (cpe->kind != kCpeLastEntry) {
648         //LOGV("+++  checking '%s' (%d)\n", cpe->fileName, cpe->kind);
649 
650         switch (cpe->kind) {
651         case kCpeDir:
652             LOGW("Directory entries ('%s') not supported in bootclasspath\n",
653                 cpe->fileName);
654             break;
655         case kCpeJar:
656             {
657                 JarFile* pJarFile = (JarFile*) cpe->ptr;
658                 const DexClassDef* pClassDef;
659                 DvmDex* pDvmDex;
660 
661                 pDvmDex = dvmGetJarFileDex(pJarFile);
662                 pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor);
663                 if (pClassDef != NULL) {
664                     /* found */
665                     pFoundDef = pClassDef;
666                     pFoundFile = pDvmDex;
667                     goto found;
668                 }
669             }
670             break;
671         case kCpeDex:
672             {
673                 RawDexFile* pRawDexFile = (RawDexFile*) cpe->ptr;
674                 const DexClassDef* pClassDef;
675                 DvmDex* pDvmDex;
676 
677                 pDvmDex = dvmGetRawDexFileDex(pRawDexFile);
678                 pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor);
679                 if (pClassDef != NULL) {
680                     /* found */
681                     pFoundDef = pClassDef;
682                     pFoundFile = pDvmDex;
683                     goto found;
684                 }
685             }
686             break;
687         default:
688             LOGE("Unknown kind %d\n", cpe->kind);
689             assert(false);
690             break;
691         }
692 
693         cpe++;
694     }
695 
696     /*
697      * Special handling during verification + optimization.
698      *
699      * The DEX optimizer needs to load classes from the DEX file it's working
700      * on.  Rather than trying to insert it into the bootstrap class path
701      * or synthesizing a class loader to manage it, we just make it available
702      * here.  It logically comes after all existing entries in the bootstrap
703      * class path.
704      */
705     if (gDvm.bootClassPathOptExtra != NULL) {
706         const DexClassDef* pClassDef;
707 
708         pClassDef =
709             dexFindClass(gDvm.bootClassPathOptExtra->pDexFile, descriptor);
710         if (pClassDef != NULL) {
711             /* found */
712             pFoundDef = pClassDef;
713             pFoundFile = gDvm.bootClassPathOptExtra;
714         }
715     }
716 
717 found:
718     *ppClassDef = pFoundDef;
719     return pFoundFile;
720 }
721 
722 /*
723  * Set the "extra" DEX, which becomes a de facto member of the bootstrap
724  * class set.
725  */
dvmSetBootPathExtraDex(DvmDex * pDvmDex)726 void dvmSetBootPathExtraDex(DvmDex* pDvmDex)
727 {
728     gDvm.bootClassPathOptExtra = pDvmDex;
729 }
730 
731 
732 /*
733  * Return the #of entries in the bootstrap class path.
734  *
735  * (Used for ClassLoader.getResources().)
736  */
dvmGetBootPathSize(void)737 int dvmGetBootPathSize(void)
738 {
739     const ClassPathEntry* cpe = gDvm.bootClassPath;
740 
741     while (cpe->kind != kCpeLastEntry)
742         cpe++;
743 
744     return cpe - gDvm.bootClassPath;
745 }
746 
747 /*
748  * Find a resource with the specified name in entry N of the boot class path.
749  *
750  * We return a newly-allocated String of one of these forms:
751  *   file://path/name
752  *   jar:file://path!/name
753  * Where "path" is the bootstrap class path entry and "name" is the string
754  * passed into this method.  "path" needs to be an absolute path (starting
755  * with '/'); if it's not we'd need to "absolutify" it as part of forming
756  * the URL string.
757  */
dvmGetBootPathResource(const char * name,int idx)758 StringObject* dvmGetBootPathResource(const char* name, int idx)
759 {
760     const int kUrlOverhead = 13;        // worst case for Jar URL
761     const ClassPathEntry* cpe = gDvm.bootClassPath;
762     StringObject* urlObj = NULL;
763 
764     LOGV("+++ searching for resource '%s' in %d(%s)\n",
765         name, idx, cpe[idx].fileName);
766 
767     /* we could use direct array index, but I don't entirely trust "idx" */
768     while (idx-- && cpe->kind != kCpeLastEntry)
769         cpe++;
770     if (cpe->kind == kCpeLastEntry) {
771         assert(false);
772         return NULL;
773     }
774 
775     char urlBuf[strlen(name) + strlen(cpe->fileName) + kUrlOverhead +1];
776 
777     switch (cpe->kind) {
778     case kCpeDir:
779         sprintf(urlBuf, "file://%s/%s", cpe->fileName, name);
780         if (access(urlBuf+7, F_OK) != 0)
781             goto bail;
782         break;
783     case kCpeJar:
784         {
785             JarFile* pJarFile = (JarFile*) cpe->ptr;
786             if (dexZipFindEntry(&pJarFile->archive, name) == NULL)
787                 goto bail;
788             sprintf(urlBuf, "jar:file://%s!/%s", cpe->fileName, name);
789         }
790         break;
791     case kCpeDex:
792         LOGV("No resources in DEX files\n");
793         goto bail;
794     default:
795         assert(false);
796         goto bail;
797     }
798 
799     LOGV("+++ using URL='%s'\n", urlBuf);
800     urlObj = dvmCreateStringFromCstr(urlBuf, ALLOC_DEFAULT);
801 
802 bail:
803     return urlObj;
804 }
805 
806 
807 /*
808  * ===========================================================================
809  *      Class list management
810  * ===========================================================================
811  */
812 
813 /* search for these criteria in the Class hash table */
814 typedef struct ClassMatchCriteria {
815     const char* descriptor;
816     Object*     loader;
817 } ClassMatchCriteria;
818 
819 #define kInitLoaderInc  4       /* must be power of 2 */
820 
dvmGetInitiatingLoaderList(ClassObject * clazz)821 static InitiatingLoaderList *dvmGetInitiatingLoaderList(ClassObject* clazz)
822 {
823     assert(clazz->serialNumber > INITIAL_CLASS_SERIAL_NUMBER);
824     int classIndex = clazz->serialNumber-INITIAL_CLASS_SERIAL_NUMBER;
825     if (gDvm.initiatingLoaderList != NULL &&
826         classIndex < ZYGOTE_CLASS_CUTOFF) {
827         return &(gDvm.initiatingLoaderList[classIndex]);
828     } else {
829         return &(clazz->initiatingLoaderList);
830     }
831 }
832 
833 /*
834  * Determine if "loader" appears in clazz' initiating loader list.
835  *
836  * The class hash table lock must be held when calling here, since
837  * it's also used when updating a class' initiating loader list.
838  *
839  * TODO: switch to some sort of lock-free data structure so we don't have
840  * to grab the lock to do a lookup.  Among other things, this would improve
841  * the speed of compareDescriptorClasses().
842  */
dvmLoaderInInitiatingList(const ClassObject * clazz,const Object * loader)843 bool dvmLoaderInInitiatingList(const ClassObject* clazz, const Object* loader)
844 {
845     /*
846      * The bootstrap class loader can't be just an initiating loader for
847      * anything (it's always the defining loader if the class is visible
848      * to it).  We don't put defining loaders in the initiating list.
849      */
850     if (loader == NULL)
851         return false;
852 
853     /*
854      * Scan the list for a match.  The list is expected to be short.
855      */
856     /* Cast to remove the const from clazz, but use const loaderList */
857     ClassObject* nonConstClazz = (ClassObject*) clazz;
858     const InitiatingLoaderList *loaderList =
859         dvmGetInitiatingLoaderList(nonConstClazz);
860     int i;
861     for (i = loaderList->initiatingLoaderCount-1; i >= 0; --i) {
862         if (loaderList->initiatingLoaders[i] == loader) {
863             //LOGI("+++ found initiating match %p in %s\n",
864             //    loader, clazz->descriptor);
865             return true;
866         }
867     }
868     return false;
869 }
870 
871 /*
872  * Add "loader" to clazz's initiating loader set, unless it's the defining
873  * class loader.
874  *
875  * In the common case this will be a short list, so we don't need to do
876  * anything too fancy here.
877  *
878  * This locks gDvm.loadedClasses for synchronization, so don't hold it
879  * when calling here.
880  */
dvmAddInitiatingLoader(ClassObject * clazz,Object * loader)881 void dvmAddInitiatingLoader(ClassObject* clazz, Object* loader)
882 {
883     if (loader != clazz->classLoader) {
884         assert(loader != NULL);
885 
886         LOGVV("Adding %p to '%s' init list\n", loader, clazz->descriptor);
887         dvmHashTableLock(gDvm.loadedClasses);
888 
889         /*
890          * Make sure nobody snuck in.  The penalty for adding twice is
891          * pretty minor, and probably outweighs the O(n^2) hit for
892          * checking before every add, so we may not want to do this.
893          */
894         //if (dvmLoaderInInitiatingList(clazz, loader)) {
895         //    LOGW("WOW: simultaneous add of initiating class loader\n");
896         //    goto bail_unlock;
897         //}
898 
899         /*
900          * The list never shrinks, so we just keep a count of the
901          * number of elements in it, and reallocate the buffer when
902          * we run off the end.
903          *
904          * The pointer is initially NULL, so we *do* want to call realloc
905          * when count==0.
906          */
907         InitiatingLoaderList *loaderList = dvmGetInitiatingLoaderList(clazz);
908         if ((loaderList->initiatingLoaderCount & (kInitLoaderInc-1)) == 0) {
909             Object** newList;
910 
911             newList = (Object**) realloc(loaderList->initiatingLoaders,
912                         (loaderList->initiatingLoaderCount + kInitLoaderInc)
913                          * sizeof(Object*));
914             if (newList == NULL) {
915                 /* this is mainly a cache, so it's not the EotW */
916                 assert(false);
917                 goto bail_unlock;
918             }
919             loaderList->initiatingLoaders = newList;
920 
921             //LOGI("Expanded init list to %d (%s)\n",
922             //    loaderList->initiatingLoaderCount+kInitLoaderInc,
923             //    clazz->descriptor);
924         }
925         loaderList->initiatingLoaders[loaderList->initiatingLoaderCount++] =
926             loader;
927 
928 bail_unlock:
929         dvmHashTableUnlock(gDvm.loadedClasses);
930     }
931 }
932 
933 /*
934  * (This is a dvmHashTableLookup callback.)
935  *
936  * Entries in the class hash table are stored as { descriptor, d-loader }
937  * tuples.  If the hashed class descriptor matches the requested descriptor,
938  * and the hashed defining class loader matches the requested class
939  * loader, we're good.  If only the descriptor matches, we check to see if the
940  * loader is in the hashed class' initiating loader list.  If so, we
941  * can return "true" immediately and skip some of the loadClass melodrama.
942  *
943  * The caller must lock the hash table before calling here.
944  *
945  * Returns 0 if a matching entry is found, nonzero otherwise.
946  */
hashcmpClassByCrit(const void * vclazz,const void * vcrit)947 static int hashcmpClassByCrit(const void* vclazz, const void* vcrit)
948 {
949     const ClassObject* clazz = (const ClassObject*) vclazz;
950     const ClassMatchCriteria* pCrit = (const ClassMatchCriteria*) vcrit;
951     bool match;
952 
953     match = (strcmp(clazz->descriptor, pCrit->descriptor) == 0 &&
954              (clazz->classLoader == pCrit->loader ||
955               (pCrit->loader != NULL &&
956                dvmLoaderInInitiatingList(clazz, pCrit->loader)) ));
957     //if (match)
958     //    LOGI("+++ %s %p matches existing %s %p\n",
959     //        pCrit->descriptor, pCrit->loader,
960     //        clazz->descriptor, clazz->classLoader);
961     return !match;
962 }
963 
964 /*
965  * Like hashcmpClassByCrit, but passing in a fully-formed ClassObject
966  * instead of a ClassMatchCriteria.
967  */
hashcmpClassByClass(const void * vclazz,const void * vaddclazz)968 static int hashcmpClassByClass(const void* vclazz, const void* vaddclazz)
969 {
970     const ClassObject* clazz = (const ClassObject*) vclazz;
971     const ClassObject* addClazz = (const ClassObject*) vaddclazz;
972     bool match;
973 
974     match = (strcmp(clazz->descriptor, addClazz->descriptor) == 0 &&
975              (clazz->classLoader == addClazz->classLoader ||
976               (addClazz->classLoader != NULL &&
977                dvmLoaderInInitiatingList(clazz, addClazz->classLoader)) ));
978     return !match;
979 }
980 
981 /*
982  * Search through the hash table to find an entry with a matching descriptor
983  * and an initiating class loader that matches "loader".
984  *
985  * The table entries are hashed on descriptor only, because they're unique
986  * on *defining* class loader, not *initiating* class loader.  This isn't
987  * great, because it guarantees we will have to probe when multiple
988  * class loaders are used.
989  *
990  * Note this does NOT try to load a class; it just finds a class that
991  * has already been loaded.
992  *
993  * If "unprepOkay" is set, this will return classes that have been added
994  * to the hash table but are not yet fully loaded and linked.  Otherwise,
995  * such classes are ignored.  (The only place that should set "unprepOkay"
996  * is findClassNoInit(), which will wait for the prep to finish.)
997  *
998  * Returns NULL if not found.
999  */
dvmLookupClass(const char * descriptor,Object * loader,bool unprepOkay)1000 ClassObject* dvmLookupClass(const char* descriptor, Object* loader,
1001     bool unprepOkay)
1002 {
1003     ClassMatchCriteria crit;
1004     void* found;
1005     u4 hash;
1006 
1007     crit.descriptor = descriptor;
1008     crit.loader = loader;
1009     hash = dvmComputeUtf8Hash(descriptor);
1010 
1011     LOGVV("threadid=%d: dvmLookupClass searching for '%s' %p\n",
1012         dvmThreadSelf()->threadId, descriptor, loader);
1013 
1014     dvmHashTableLock(gDvm.loadedClasses);
1015     found = dvmHashTableLookup(gDvm.loadedClasses, hash, &crit,
1016                 hashcmpClassByCrit, false);
1017     dvmHashTableUnlock(gDvm.loadedClasses);
1018 
1019     /*
1020      * The class has been added to the hash table but isn't ready for use.
1021      * We're going to act like we didn't see it, so that the caller will
1022      * go through the full "find class" path, which includes locking the
1023      * object and waiting until it's ready.  We could do that lock/wait
1024      * here, but this is an extremely rare case, and it's simpler to have
1025      * the wait-for-class code centralized.
1026      */
1027     if (found != NULL && !unprepOkay && !dvmIsClassLinked(found)) {
1028         LOGV("Ignoring not-yet-ready %s, using slow path\n",
1029             ((ClassObject*)found)->descriptor);
1030         found = NULL;
1031     }
1032 
1033     return (ClassObject*) found;
1034 }
1035 
1036 /*
1037  * Add a new class to the hash table.
1038  *
1039  * The class is considered "new" if it doesn't match on both the class
1040  * descriptor and the defining class loader.
1041  *
1042  * TODO: we should probably have separate hash tables for each
1043  * ClassLoader. This could speed up dvmLookupClass and
1044  * other common operations. It does imply a VM-visible data structure
1045  * for each ClassLoader object with loaded classes, which we don't
1046  * have yet.
1047  */
dvmAddClassToHash(ClassObject * clazz)1048 bool dvmAddClassToHash(ClassObject* clazz)
1049 {
1050     void* found;
1051     u4 hash;
1052 
1053     hash = dvmComputeUtf8Hash(clazz->descriptor);
1054 
1055     dvmHashTableLock(gDvm.loadedClasses);
1056     found = dvmHashTableLookup(gDvm.loadedClasses, hash, clazz,
1057                 hashcmpClassByClass, true);
1058     dvmHashTableUnlock(gDvm.loadedClasses);
1059 
1060     LOGV("+++ dvmAddClassToHash '%s' %p (isnew=%d) --> %p\n",
1061         clazz->descriptor, clazz->classLoader,
1062         (found == (void*) clazz), clazz);
1063 
1064     //dvmCheckClassTablePerf();
1065 
1066     /* can happen if two threads load the same class simultaneously */
1067     return (found == (void*) clazz);
1068 }
1069 
1070 #if 0
1071 /*
1072  * Compute hash value for a class.
1073  */
1074 u4 hashcalcClass(const void* item)
1075 {
1076     return dvmComputeUtf8Hash(((const ClassObject*) item)->descriptor);
1077 }
1078 
1079 /*
1080  * Check the performance of the "loadedClasses" hash table.
1081  */
1082 void dvmCheckClassTablePerf(void)
1083 {
1084     dvmHashTableLock(gDvm.loadedClasses);
1085     dvmHashTableProbeCount(gDvm.loadedClasses, hashcalcClass,
1086         hashcmpClassByClass);
1087     dvmHashTableUnlock(gDvm.loadedClasses);
1088 }
1089 #endif
1090 
1091 /*
1092  * Remove a class object from the hash table.
1093  */
removeClassFromHash(ClassObject * clazz)1094 static void removeClassFromHash(ClassObject* clazz)
1095 {
1096     LOGV("+++ removeClassFromHash '%s'\n", clazz->descriptor);
1097 
1098     u4 hash = dvmComputeUtf8Hash(clazz->descriptor);
1099 
1100     dvmHashTableLock(gDvm.loadedClasses);
1101     if (!dvmHashTableRemove(gDvm.loadedClasses, hash, clazz))
1102         LOGW("Hash table remove failed on class '%s'\n", clazz->descriptor);
1103     dvmHashTableUnlock(gDvm.loadedClasses);
1104 }
1105 
1106 
1107 /*
1108  * ===========================================================================
1109  *      Class creation
1110  * ===========================================================================
1111  */
1112 
1113 /*
1114  * Set clazz->serialNumber to the next available value.
1115  *
1116  * This usually happens *very* early in class creation, so don't expect
1117  * anything else in the class to be ready.
1118  */
dvmSetClassSerialNumber(ClassObject * clazz)1119 void dvmSetClassSerialNumber(ClassObject* clazz)
1120 {
1121     u4 oldValue, newValue;
1122 
1123     assert(clazz->serialNumber == 0);
1124 
1125     do {
1126         oldValue = gDvm.classSerialNumber;
1127         newValue = oldValue + 1;
1128     } while (!ATOMIC_CMP_SWAP(&gDvm.classSerialNumber, oldValue, newValue));
1129 
1130     clazz->serialNumber = (u4) oldValue;
1131 }
1132 
1133 
1134 /*
1135  * Find the named class (by descriptor), using the specified
1136  * initiating ClassLoader.
1137  *
1138  * The class will be loaded and initialized if it has not already been.
1139  * If necessary, the superclass will be loaded.
1140  *
1141  * If the class can't be found, returns NULL with an appropriate exception
1142  * raised.
1143  */
dvmFindClass(const char * descriptor,Object * loader)1144 ClassObject* dvmFindClass(const char* descriptor, Object* loader)
1145 {
1146     ClassObject* clazz;
1147 
1148     clazz = dvmFindClassNoInit(descriptor, loader);
1149     if (clazz != NULL && clazz->status < CLASS_INITIALIZED) {
1150         /* initialize class */
1151         if (!dvmInitClass(clazz)) {
1152             /* init failed; leave it in the list, marked as bad */
1153             assert(dvmCheckException(dvmThreadSelf()));
1154             assert(clazz->status == CLASS_ERROR);
1155             return NULL;
1156         }
1157     }
1158 
1159     return clazz;
1160 }
1161 
1162 /*
1163  * Find the named class (by descriptor), using the specified
1164  * initiating ClassLoader.
1165  *
1166  * The class will be loaded if it has not already been, as will its
1167  * superclass.  It will not be initialized.
1168  *
1169  * If the class can't be found, returns NULL with an appropriate exception
1170  * raised.
1171  */
dvmFindClassNoInit(const char * descriptor,Object * loader)1172 ClassObject* dvmFindClassNoInit(const char* descriptor,
1173         Object* loader)
1174 {
1175     assert(descriptor != NULL);
1176     //assert(loader != NULL);
1177 
1178     LOGVV("FindClassNoInit '%s' %p\n", descriptor, loader);
1179 
1180     if (*descriptor == '[') {
1181         /*
1182          * Array class.  Find in table, generate if not found.
1183          */
1184         return dvmFindArrayClass(descriptor, loader);
1185     } else {
1186         /*
1187          * Regular class.  Find in table, load if not found.
1188          */
1189         if (loader != NULL) {
1190             return findClassFromLoaderNoInit(descriptor, loader);
1191         } else {
1192             return dvmFindSystemClassNoInit(descriptor);
1193         }
1194     }
1195 }
1196 
1197 /*
1198  * Load the named class (by descriptor) from the specified class
1199  * loader.  This calls out to let the ClassLoader object do its thing.
1200  *
1201  * Returns with NULL and an exception raised on error.
1202  */
findClassFromLoaderNoInit(const char * descriptor,Object * loader)1203 static ClassObject* findClassFromLoaderNoInit(const char* descriptor,
1204     Object* loader)
1205 {
1206     //LOGI("##### findClassFromLoaderNoInit (%s,%p)\n",
1207     //        descriptor, loader);
1208 
1209     Thread* self = dvmThreadSelf();
1210     ClassObject* clazz;
1211 
1212     assert(loader != NULL);
1213 
1214     /*
1215      * Do we already have it?
1216      *
1217      * The class loader code does the "is it already loaded" check as
1218      * well.  However, this call is much faster than calling through
1219      * interpreted code.  Doing this does mean that in the common case
1220      * (365 out of 420 calls booting the sim) we're doing the
1221      * lookup-by-descriptor twice.  It appears this is still a win, so
1222      * I'm keeping it in.
1223      */
1224     clazz = dvmLookupClass(descriptor, loader, false);
1225     if (clazz != NULL) {
1226         LOGVV("Already loaded: %s %p\n", descriptor, loader);
1227         return clazz;
1228     } else {
1229         LOGVV("Not already loaded: %s %p\n", descriptor, loader);
1230     }
1231 
1232     char* dotName = NULL;
1233     StringObject* nameObj = NULL;
1234     Object* excep;
1235     Method* loadClass;
1236 
1237     /* convert "Landroid/debug/Stuff;" to "android.debug.Stuff" */
1238     dotName = dvmDescriptorToDot(descriptor);
1239     if (dotName == NULL) {
1240         dvmThrowException("Ljava/lang/OutOfMemoryError;", NULL);
1241         goto bail;
1242     }
1243     nameObj = dvmCreateStringFromCstr(dotName, ALLOC_DEFAULT);
1244     if (nameObj == NULL) {
1245         assert(dvmCheckException(self));
1246         goto bail;
1247     }
1248 
1249     // TODO: cache the vtable offset
1250     loadClass = dvmFindVirtualMethodHierByDescriptor(loader->clazz, "loadClass",
1251                  "(Ljava/lang/String;)Ljava/lang/Class;");
1252     if (loadClass == NULL) {
1253         LOGW("Couldn't find loadClass in ClassLoader\n");
1254         goto bail;
1255     }
1256 
1257 #ifdef WITH_PROFILER
1258     dvmMethodTraceClassPrepBegin();
1259 #endif
1260 
1261     /*
1262      * Invoke loadClass().  This will probably result in a couple of
1263      * exceptions being thrown, because the ClassLoader.loadClass()
1264      * implementation eventually calls VMClassLoader.loadClass to see if
1265      * the bootstrap class loader can find it before doing its own load.
1266      */
1267     LOGVV("--- Invoking loadClass(%s, %p)\n", dotName, loader);
1268     JValue result;
1269     dvmCallMethod(self, loadClass, loader, &result, nameObj);
1270     clazz = (ClassObject*) result.l;
1271 
1272 #ifdef WITH_PROFILER
1273     dvmMethodTraceClassPrepEnd();
1274 #endif
1275 
1276     excep = dvmGetException(self);
1277     if (excep != NULL) {
1278 #if DVM_SHOW_EXCEPTION >= 2
1279         LOGD("NOTE: loadClass '%s' %p threw exception %s\n",
1280             dotName, loader, excep->clazz->descriptor);
1281 #endif
1282         dvmAddTrackedAlloc(excep, self);
1283         dvmClearException(self);
1284         dvmThrowChainedExceptionWithClassMessage(
1285             "Ljava/lang/NoClassDefFoundError;", descriptor, excep);
1286         dvmReleaseTrackedAlloc(excep, self);
1287         clazz = NULL;
1288         goto bail;
1289     } else {
1290         assert(clazz != NULL);
1291     }
1292 
1293     dvmAddInitiatingLoader(clazz, loader);
1294 
1295     LOGVV("--- Successfully loaded %s %p (thisldr=%p clazz=%p)\n",
1296         descriptor, clazz->classLoader, loader, clazz);
1297 
1298 bail:
1299     dvmReleaseTrackedAlloc((Object*)nameObj, NULL);
1300     free(dotName);
1301     return clazz;
1302 }
1303 
1304 /*
1305  * Load the named class (by descriptor) from the specified DEX file.
1306  * Used by class loaders to instantiate a class object from a
1307  * VM-managed DEX.
1308  */
dvmDefineClass(DvmDex * pDvmDex,const char * descriptor,Object * classLoader)1309 ClassObject* dvmDefineClass(DvmDex* pDvmDex, const char* descriptor,
1310     Object* classLoader)
1311 {
1312     assert(pDvmDex != NULL);
1313 
1314     return findClassNoInit(descriptor, classLoader, pDvmDex);
1315 }
1316 
1317 
1318 /*
1319  * Find the named class (by descriptor), scanning through the
1320  * bootclasspath if it hasn't already been loaded.
1321  *
1322  * "descriptor" looks like "Landroid/debug/Stuff;".
1323  *
1324  * Uses NULL as the defining class loader.
1325  */
dvmFindSystemClass(const char * descriptor)1326 ClassObject* dvmFindSystemClass(const char* descriptor)
1327 {
1328     ClassObject* clazz;
1329 
1330     clazz = dvmFindSystemClassNoInit(descriptor);
1331     if (clazz != NULL && clazz->status < CLASS_INITIALIZED) {
1332         /* initialize class */
1333         if (!dvmInitClass(clazz)) {
1334             /* init failed; leave it in the list, marked as bad */
1335             assert(dvmCheckException(dvmThreadSelf()));
1336             assert(clazz->status == CLASS_ERROR);
1337             return NULL;
1338         }
1339     }
1340 
1341     return clazz;
1342 }
1343 
1344 /*
1345  * Find the named class (by descriptor), searching for it in the
1346  * bootclasspath.
1347  *
1348  * On failure, this returns NULL with an exception raised.
1349  */
dvmFindSystemClassNoInit(const char * descriptor)1350 ClassObject* dvmFindSystemClassNoInit(const char* descriptor)
1351 {
1352     return findClassNoInit(descriptor, NULL, NULL);
1353 }
1354 
1355 /*
1356  * Find the named class (by descriptor). If it's not already loaded,
1357  * we load it and link it, but don't execute <clinit>. (The VM has
1358  * specific limitations on which events can cause initialization.)
1359  *
1360  * If "pDexFile" is NULL, we will search the bootclasspath for an entry.
1361  *
1362  * On failure, this returns NULL with an exception raised.
1363  *
1364  * TODO: we need to return an indication of whether we loaded the class or
1365  * used an existing definition.  If somebody deliberately tries to load a
1366  * class twice in the same class loader, they should get a LinkageError,
1367  * but inadvertent simultaneous class references should "just work".
1368  */
findClassNoInit(const char * descriptor,Object * loader,DvmDex * pDvmDex)1369 static ClassObject* findClassNoInit(const char* descriptor, Object* loader,
1370     DvmDex* pDvmDex)
1371 {
1372     Thread* self = dvmThreadSelf();
1373     ClassObject* clazz;
1374 #ifdef WITH_PROFILER
1375     bool profilerNotified = false;
1376 #endif
1377 
1378     if (loader != NULL) {
1379         LOGVV("#### findClassNoInit(%s,%p,%p)\n", descriptor, loader,
1380             pDvmDex->pDexFile);
1381     }
1382 
1383     /*
1384      * We don't expect an exception to be raised at this point.  The
1385      * exception handling code is good about managing this.  This *can*
1386      * happen if a JNI lookup fails and the JNI code doesn't do any
1387      * error checking before doing another class lookup, so we may just
1388      * want to clear this and restore it on exit.  If we don't, some kinds
1389      * of failures can't be detected without rearranging other stuff.
1390      *
1391      * Most often when we hit this situation it means that something is
1392      * broken in the VM or in JNI code, so I'm keeping it in place (and
1393      * making it an informative abort rather than an assert).
1394      */
1395     if (dvmCheckException(self)) {
1396         LOGE("Class lookup %s attemped while exception %s pending\n",
1397             descriptor, dvmGetException(self)->clazz->descriptor);
1398         dvmDumpAllThreads(false);
1399         dvmAbort();
1400     }
1401 
1402     clazz = dvmLookupClass(descriptor, loader, true);
1403     if (clazz == NULL) {
1404         const DexClassDef* pClassDef;
1405 
1406 #ifdef WITH_PROFILER
1407         dvmMethodTraceClassPrepBegin();
1408         profilerNotified = true;
1409 #endif
1410 
1411 #if LOG_CLASS_LOADING
1412         u8 startTime = dvmGetThreadCpuTimeNsec();
1413 #endif
1414 
1415         if (pDvmDex == NULL) {
1416             assert(loader == NULL);     /* shouldn't be here otherwise */
1417             pDvmDex = searchBootPathForClass(descriptor, &pClassDef);
1418         } else {
1419             pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor);
1420         }
1421 
1422         if (pDvmDex == NULL || pClassDef == NULL) {
1423             if (gDvm.noClassDefFoundErrorObj != NULL) {
1424                 /* usual case -- use prefabricated object */
1425                 dvmSetException(self, gDvm.noClassDefFoundErrorObj);
1426             } else {
1427                 /* dexopt case -- can't guarantee prefab (core.jar) */
1428                 dvmThrowExceptionWithClassMessage(
1429                     "Ljava/lang/NoClassDefFoundError;", descriptor);
1430             }
1431             goto bail;
1432         }
1433 
1434         /* found a match, try to load it */
1435         clazz = loadClassFromDex(pDvmDex, pClassDef, loader);
1436         if (dvmCheckException(self)) {
1437             /* class was found but had issues */
1438             dvmReleaseTrackedAlloc((Object*) clazz, NULL);
1439             goto bail;
1440         }
1441 
1442         /*
1443          * Lock the class while we link it so other threads must wait for us
1444          * to finish.  Set the "initThreadId" so we can identify recursive
1445          * invocation.
1446          */
1447         dvmLockObject(self, (Object*) clazz);
1448         clazz->initThreadId = self->threadId;
1449 
1450         /*
1451          * Add to hash table so lookups succeed.
1452          *
1453          * [Are circular references possible when linking a class?]
1454          */
1455         assert(clazz->classLoader == loader);
1456         if (!dvmAddClassToHash(clazz)) {
1457             /*
1458              * Another thread must have loaded the class after we
1459              * started but before we finished.  Discard what we've
1460              * done and leave some hints for the GC.
1461              *
1462              * (Yes, this happens.)
1463              */
1464             //LOGW("WOW: somebody loaded %s simultaneously\n", descriptor);
1465             clazz->initThreadId = 0;
1466             dvmUnlockObject(self, (Object*) clazz);
1467 
1468             /* Let the GC free the class.
1469              */
1470             assert(clazz->obj.clazz == gDvm.unlinkedJavaLangClass);
1471             dvmReleaseTrackedAlloc((Object*) clazz, NULL);
1472 
1473             /* Grab the winning class.
1474              */
1475             clazz = dvmLookupClass(descriptor, loader, true);
1476             assert(clazz != NULL);
1477             goto got_class;
1478         }
1479         dvmReleaseTrackedAlloc((Object*) clazz, NULL);
1480 
1481 #if LOG_CLASS_LOADING
1482         logClassLoadWithTime('>', clazz, startTime);
1483 #endif
1484         /*
1485          * Prepare and resolve.
1486          */
1487         if (!dvmLinkClass(clazz, false)) {
1488             assert(dvmCheckException(self));
1489 
1490             /* Make note of the error and clean up the class.
1491              */
1492             removeClassFromHash(clazz);
1493             clazz->status = CLASS_ERROR;
1494             dvmFreeClassInnards(clazz);
1495 
1496             /* Let any waiters know.
1497              */
1498             clazz->initThreadId = 0;
1499             dvmObjectNotifyAll(self, (Object*) clazz);
1500             dvmUnlockObject(self, (Object*) clazz);
1501 
1502 #if LOG_CLASS_LOADING
1503             LOG(LOG_INFO, "DVMLINK FAILED FOR CLASS ", "%s in %s\n",
1504                 clazz->descriptor, get_process_name());
1505 
1506             /*
1507              * TODO: It would probably be better to use a new type code here (instead of '<') to
1508              * indicate the failure.  This change would require a matching change in the parser
1509              * and analysis code in frameworks/base/tools/preload.
1510              */
1511             logClassLoad('<', clazz);
1512 #endif
1513             clazz = NULL;
1514             if (gDvm.optimizing) {
1515                 /* happens with "external" libs */
1516                 LOGV("Link of class '%s' failed\n", descriptor);
1517             } else {
1518                 LOGW("Link of class '%s' failed\n", descriptor);
1519             }
1520             goto bail;
1521         }
1522         dvmObjectNotifyAll(self, (Object*) clazz);
1523         dvmUnlockObject(self, (Object*) clazz);
1524 
1525         /*
1526          * Add class stats to global counters.
1527          *
1528          * TODO: these should probably be atomic ops.
1529          */
1530         gDvm.numLoadedClasses++;
1531         gDvm.numDeclaredMethods +=
1532             clazz->virtualMethodCount + clazz->directMethodCount;
1533         gDvm.numDeclaredInstFields += clazz->ifieldCount;
1534         gDvm.numDeclaredStaticFields += clazz->sfieldCount;
1535 
1536         /*
1537          * Cache pointers to basic classes.  We want to use these in
1538          * various places, and it's easiest to initialize them on first
1539          * use rather than trying to force them to initialize (startup
1540          * ordering makes it weird).
1541          */
1542         if (gDvm.classJavaLangObject == NULL &&
1543             strcmp(descriptor, "Ljava/lang/Object;") == 0)
1544         {
1545             /* It should be impossible to get here with anything
1546              * but the bootclasspath loader.
1547              */
1548             assert(loader == NULL);
1549             gDvm.classJavaLangObject = clazz;
1550         }
1551 
1552 #if LOG_CLASS_LOADING
1553         logClassLoad('<', clazz);
1554 #endif
1555 
1556     } else {
1557 got_class:
1558         if (!dvmIsClassLinked(clazz) && clazz->status != CLASS_ERROR) {
1559             /*
1560              * We can race with other threads for class linking.  We should
1561              * never get here recursively; doing so indicates that two
1562              * classes have circular dependencies.
1563              *
1564              * One exception: we force discovery of java.lang.Class in
1565              * dvmLinkClass(), and Class has Object as its superclass.  So
1566              * if the first thing we ever load is Object, we will init
1567              * Object->Class->Object.  The easiest way to avoid this is to
1568              * ensure that Object is never the first thing we look up, so
1569              * we get Foo->Class->Object instead.
1570              */
1571             dvmLockObject(self, (Object*) clazz);
1572             if (!dvmIsClassLinked(clazz) &&
1573                 clazz->initThreadId == self->threadId)
1574             {
1575                 LOGW("Recursive link on class %s\n", clazz->descriptor);
1576                 dvmUnlockObject(self, (Object*) clazz);
1577                 dvmThrowExceptionWithClassMessage(
1578                     "Ljava/lang/ClassCircularityError;", clazz->descriptor);
1579                 clazz = NULL;
1580                 goto bail;
1581             }
1582             //LOGI("WAITING  for '%s' (owner=%d)\n",
1583             //    clazz->descriptor, clazz->initThreadId);
1584             while (!dvmIsClassLinked(clazz) && clazz->status != CLASS_ERROR) {
1585                 dvmObjectWait(self, (Object*) clazz, 0, 0, false);
1586             }
1587             dvmUnlockObject(self, (Object*) clazz);
1588         }
1589         if (clazz->status == CLASS_ERROR) {
1590             /*
1591              * Somebody else tried to load this and failed.  We need to raise
1592              * an exception and report failure.
1593              */
1594             throwEarlierClassFailure(clazz);
1595             clazz = NULL;
1596             goto bail;
1597         }
1598     }
1599 
1600     /* check some invariants */
1601     assert(dvmIsClassLinked(clazz));
1602     assert(gDvm.classJavaLangClass != NULL);
1603     assert(clazz->obj.clazz == gDvm.classJavaLangClass);
1604     if (clazz != gDvm.classJavaLangObject) {
1605         if (clazz->super == NULL) {
1606             LOGE("Non-Object has no superclass (gDvm.classJavaLangObject=%p)\n",
1607                 gDvm.classJavaLangObject);
1608             dvmAbort();
1609         }
1610     }
1611     if (!dvmIsInterfaceClass(clazz)) {
1612         //LOGI("class=%s vtableCount=%d, virtualMeth=%d\n",
1613         //    clazz->descriptor, clazz->vtableCount,
1614         //    clazz->virtualMethodCount);
1615         assert(clazz->vtableCount >= clazz->virtualMethodCount);
1616     }
1617 
1618     /*
1619      * Normally class objects are initialized before we instantiate them,
1620      * but we can't do that with java.lang.Class (chicken, meet egg).  We
1621      * do it explicitly here.
1622      *
1623      * The verifier could call here to find Class while verifying Class,
1624      * so we need to check for CLASS_VERIFYING as well as !initialized.
1625      */
1626     if (clazz == gDvm.classJavaLangClass && !dvmIsClassInitialized(clazz) &&
1627         !(clazz->status == CLASS_VERIFYING))
1628     {
1629         LOGV("+++ explicitly initializing %s\n", clazz->descriptor);
1630         dvmInitClass(clazz);
1631     }
1632 
1633 bail:
1634 #ifdef WITH_PROFILER
1635     if (profilerNotified)
1636         dvmMethodTraceClassPrepEnd();
1637 #endif
1638     assert(clazz != NULL || dvmCheckException(self));
1639     return clazz;
1640 }
1641 
1642 /*
1643  * Helper for loadClassFromDex, which takes a DexClassDataHeader and
1644  * encoded data pointer in addition to the other arguments.
1645  */
loadClassFromDex0(DvmDex * pDvmDex,const DexClassDef * pClassDef,const DexClassDataHeader * pHeader,const u1 * pEncodedData,Object * classLoader)1646 static ClassObject* loadClassFromDex0(DvmDex* pDvmDex,
1647     const DexClassDef* pClassDef, const DexClassDataHeader* pHeader,
1648     const u1* pEncodedData, Object* classLoader)
1649 {
1650     ClassObject* newClass = NULL;
1651     const DexFile* pDexFile;
1652     const char* descriptor;
1653     int i;
1654 
1655     pDexFile = pDvmDex->pDexFile;
1656     descriptor = dexGetClassDescriptor(pDexFile, pClassDef);
1657 
1658     /*
1659      * Make sure the aren't any "bonus" flags set, since we use them for
1660      * runtime state.
1661      */
1662     if ((pClassDef->accessFlags & ~EXPECTED_FILE_FLAGS) != 0) {
1663         LOGW("Invalid file flags in class %s: %04x\n",
1664             descriptor, pClassDef->accessFlags);
1665         return NULL;
1666     }
1667 
1668     /*
1669      * Allocate storage for the class object on the GC heap, so that other
1670      * objects can have references to it.  We bypass the usual mechanism
1671      * (allocObject), because we don't have all the bits and pieces yet.
1672      *
1673      * Note that we assume that java.lang.Class does not override
1674      * finalize().
1675      */
1676     newClass = (ClassObject*) dvmMalloc(sizeof(*newClass), ALLOC_DEFAULT);
1677     if (newClass == NULL)
1678         return NULL;
1679 
1680     /* Until the class is loaded and linked, use a placeholder
1681      * obj->clazz value as a hint to the GC.  We don't want
1682      * the GC trying to scan the object while it's full of Idx
1683      * values.  Also, the real java.lang.Class may not exist
1684      * yet.
1685      */
1686     DVM_OBJECT_INIT(&newClass->obj, gDvm.unlinkedJavaLangClass);
1687 
1688     dvmSetClassSerialNumber(newClass);
1689     newClass->descriptor = descriptor;
1690     assert(newClass->descriptorAlloc == NULL);
1691     newClass->accessFlags = pClassDef->accessFlags;
1692     newClass->classLoader = classLoader;
1693     newClass->pDvmDex = pDvmDex;
1694     newClass->primitiveType = PRIM_NOT;
1695 
1696     /*
1697      * Stuff the superclass index into the object pointer field.  The linker
1698      * pulls it out and replaces it with a resolved ClassObject pointer.
1699      * I'm doing it this way (rather than having a dedicated superclassIdx
1700      * field) to save a few bytes of overhead per class.
1701      *
1702      * newClass->super is not traversed or freed by dvmFreeClassInnards, so
1703      * this is safe.
1704      */
1705     assert(sizeof(u4) == sizeof(ClassObject*));
1706     newClass->super = (ClassObject*) pClassDef->superclassIdx;
1707 
1708     /*
1709      * Stuff class reference indices into the pointer fields.
1710      *
1711      * The elements of newClass->interfaces are not traversed or freed by
1712      * dvmFreeClassInnards, so this is GC-safe.
1713      */
1714     const DexTypeList* pInterfacesList;
1715     pInterfacesList = dexGetInterfacesList(pDexFile, pClassDef);
1716     if (pInterfacesList != NULL) {
1717         newClass->interfaceCount = pInterfacesList->size;
1718         newClass->interfaces = (ClassObject**) dvmLinearAlloc(classLoader,
1719                 newClass->interfaceCount * sizeof(ClassObject*));
1720 
1721         for (i = 0; i < newClass->interfaceCount; i++) {
1722             const DexTypeItem* pType = dexGetTypeItem(pInterfacesList, i);
1723             newClass->interfaces[i] = (ClassObject*)(u4) pType->typeIdx;
1724         }
1725         dvmLinearReadOnly(classLoader, newClass->interfaces);
1726     }
1727 
1728     /* load field definitions */
1729 
1730     /*
1731      * TODO: consider over-allocating the class object and appending the
1732      * static field info onto the end.  It's fixed-size and known at alloc
1733      * time.  This would save a couple of native heap allocations, but it
1734      * would also make heap compaction more difficult because we pass Field
1735      * pointers around internally.
1736      */
1737 
1738     if (pHeader->staticFieldsSize != 0) {
1739         /* static fields stay on system heap; field data isn't "write once" */
1740         int count = (int) pHeader->staticFieldsSize;
1741         u4 lastIndex = 0;
1742         DexField field;
1743 
1744         newClass->sfieldCount = count;
1745         newClass->sfields =
1746             (StaticField*) calloc(count, sizeof(StaticField));
1747         for (i = 0; i < count; i++) {
1748             dexReadClassDataField(&pEncodedData, &field, &lastIndex);
1749             loadSFieldFromDex(newClass, &field, &newClass->sfields[i]);
1750         }
1751     }
1752 
1753     if (pHeader->instanceFieldsSize != 0) {
1754         int count = (int) pHeader->instanceFieldsSize;
1755         u4 lastIndex = 0;
1756         DexField field;
1757 
1758         newClass->ifieldCount = count;
1759         newClass->ifields = (InstField*) dvmLinearAlloc(classLoader,
1760                 count * sizeof(InstField));
1761         for (i = 0; i < count; i++) {
1762             dexReadClassDataField(&pEncodedData, &field, &lastIndex);
1763             loadIFieldFromDex(newClass, &field, &newClass->ifields[i]);
1764         }
1765         dvmLinearReadOnly(classLoader, newClass->ifields);
1766     }
1767 
1768     /*
1769      * Load method definitions.  We do this in two batches, direct then
1770      * virtual.
1771      *
1772      * If register maps have already been generated for this class, and
1773      * precise GC is enabled, we pull out pointers to them.  We know that
1774      * they were streamed to the DEX file in the same order in which the
1775      * methods appear.
1776      *
1777      * If the class wasn't pre-verified, the maps will be generated when
1778      * the class is verified during class initialization.
1779      */
1780     u4 classDefIdx = dexGetIndexForClassDef(pDexFile, pClassDef);
1781     const void* classMapData;
1782     u4 numMethods;
1783 
1784     if (gDvm.preciseGc) {
1785         classMapData =
1786             dvmRegisterMapGetClassData(pDexFile, classDefIdx, &numMethods);
1787 
1788         /* sanity check */
1789         if (classMapData != NULL &&
1790             pHeader->directMethodsSize + pHeader->virtualMethodsSize != numMethods)
1791         {
1792             LOGE("ERROR: in %s, direct=%d virtual=%d, maps have %d\n",
1793                 newClass->descriptor, pHeader->directMethodsSize,
1794                 pHeader->virtualMethodsSize, numMethods);
1795             assert(false);
1796             classMapData = NULL;        /* abandon */
1797         }
1798     } else {
1799         classMapData = NULL;
1800     }
1801 
1802     if (pHeader->directMethodsSize != 0) {
1803         int count = (int) pHeader->directMethodsSize;
1804         u4 lastIndex = 0;
1805         DexMethod method;
1806 
1807         newClass->directMethodCount = count;
1808         newClass->directMethods = (Method*) dvmLinearAlloc(classLoader,
1809                 count * sizeof(Method));
1810         for (i = 0; i < count; i++) {
1811             dexReadClassDataMethod(&pEncodedData, &method, &lastIndex);
1812             loadMethodFromDex(newClass, &method, &newClass->directMethods[i]);
1813             if (classMapData != NULL) {
1814                 const RegisterMap* pMap = dvmRegisterMapGetNext(&classMapData);
1815                 if (dvmRegisterMapGetFormat(pMap) != kRegMapFormatNone) {
1816                     newClass->directMethods[i].registerMap = pMap;
1817                     /* TODO: add rigorous checks */
1818                     assert((newClass->directMethods[i].registersSize+7) / 8 ==
1819                         newClass->directMethods[i].registerMap->regWidth);
1820                 }
1821             }
1822         }
1823         dvmLinearReadOnly(classLoader, newClass->directMethods);
1824     }
1825 
1826     if (pHeader->virtualMethodsSize != 0) {
1827         int count = (int) pHeader->virtualMethodsSize;
1828         u4 lastIndex = 0;
1829         DexMethod method;
1830 
1831         newClass->virtualMethodCount = count;
1832         newClass->virtualMethods = (Method*) dvmLinearAlloc(classLoader,
1833                 count * sizeof(Method));
1834         for (i = 0; i < count; i++) {
1835             dexReadClassDataMethod(&pEncodedData, &method, &lastIndex);
1836             loadMethodFromDex(newClass, &method, &newClass->virtualMethods[i]);
1837             if (classMapData != NULL) {
1838                 const RegisterMap* pMap = dvmRegisterMapGetNext(&classMapData);
1839                 if (dvmRegisterMapGetFormat(pMap) != kRegMapFormatNone) {
1840                     newClass->virtualMethods[i].registerMap = pMap;
1841                     /* TODO: add rigorous checks */
1842                     assert((newClass->virtualMethods[i].registersSize+7) / 8 ==
1843                         newClass->virtualMethods[i].registerMap->regWidth);
1844                 }
1845             }
1846         }
1847         dvmLinearReadOnly(classLoader, newClass->virtualMethods);
1848     }
1849 
1850     newClass->sourceFile = dexGetSourceFile(pDexFile, pClassDef);
1851     newClass->status = CLASS_LOADED;
1852 
1853     /* caller must call dvmReleaseTrackedAlloc */
1854     return newClass;
1855 }
1856 
1857 /*
1858  * Try to load the indicated class from the specified DEX file.
1859  *
1860  * This is effectively loadClass()+defineClass() for a DexClassDef.  The
1861  * loading was largely done when we crunched through the DEX.
1862  *
1863  * Returns NULL on failure.  If we locate the class but encounter an error
1864  * while processing it, an appropriate exception is thrown.
1865  */
loadClassFromDex(DvmDex * pDvmDex,const DexClassDef * pClassDef,Object * classLoader)1866 static ClassObject* loadClassFromDex(DvmDex* pDvmDex,
1867     const DexClassDef* pClassDef, Object* classLoader)
1868 {
1869     ClassObject* result;
1870     DexClassDataHeader header;
1871     const u1* pEncodedData;
1872     const DexFile* pDexFile;
1873 
1874     assert((pDvmDex != NULL) && (pClassDef != NULL));
1875     pDexFile = pDvmDex->pDexFile;
1876 
1877     if (gDvm.verboseClass) {
1878         LOGV("CLASS: loading '%s'...\n",
1879             dexGetClassDescriptor(pDexFile, pClassDef));
1880     }
1881 
1882     pEncodedData = dexGetClassData(pDexFile, pClassDef);
1883 
1884     if (pEncodedData != NULL) {
1885         dexReadClassDataHeader(&pEncodedData, &header);
1886     } else {
1887         // Provide an all-zeroes header for the rest of the loading.
1888         memset(&header, 0, sizeof(header));
1889     }
1890 
1891     result = loadClassFromDex0(pDvmDex, pClassDef, &header, pEncodedData,
1892             classLoader);
1893 
1894     if (gDvm.verboseClass && (result != NULL)) {
1895         LOGI("[Loaded %s from DEX %p (cl=%p)]\n",
1896             result->descriptor, pDvmDex, classLoader);
1897     }
1898 
1899     return result;
1900 }
1901 
1902 /*
1903  * Free anything in a ClassObject that was allocated on the system heap.
1904  *
1905  * The ClassObject itself is allocated on the GC heap, so we leave it for
1906  * the garbage collector.
1907  *
1908  * NOTE: this may be called with a partially-constructed object.
1909  * NOTE: there is no particular ordering imposed, so don't go poking at
1910  * superclasses.
1911  */
dvmFreeClassInnards(ClassObject * clazz)1912 void dvmFreeClassInnards(ClassObject* clazz)
1913 {
1914     void *tp;
1915     int i;
1916 
1917     if (clazz == NULL)
1918         return;
1919 
1920     assert(clazz->obj.clazz == gDvm.classJavaLangClass ||
1921            clazz->obj.clazz == gDvm.unlinkedJavaLangClass);
1922 
1923     /* Guarantee that dvmFreeClassInnards can be called on a given
1924      * class multiple times by clearing things out as we free them.
1925      * We don't make any attempt at real atomicity here; higher
1926      * levels need to make sure that no two threads can free the
1927      * same ClassObject at the same time.
1928      *
1929      * TODO: maybe just make it so the GC will never free the
1930      * innards of an already-freed class.
1931      *
1932      * TODO: this #define isn't MT-safe -- the compiler could rearrange it.
1933      */
1934 #define NULL_AND_FREE(p) \
1935     do { \
1936         if ((p) != NULL) { \
1937             tp = (p); \
1938             (p) = NULL; \
1939             free(tp); \
1940         } \
1941     } while (0)
1942 #define NULL_AND_LINEAR_FREE(p) \
1943     do { \
1944         if ((p) != NULL) { \
1945             tp = (p); \
1946             (p) = NULL; \
1947             dvmLinearFree(clazz->classLoader, tp); \
1948         } \
1949     } while (0)
1950 
1951     /* arrays just point at Object's vtable; don't free vtable in this case.
1952      * dvmIsArrayClass() checks clazz->descriptor, so we have to do this check
1953      * before freeing the name.
1954      */
1955     clazz->vtableCount = -1;
1956     if (dvmIsArrayClass(clazz)) {
1957         clazz->vtable = NULL;
1958     } else {
1959         NULL_AND_LINEAR_FREE(clazz->vtable);
1960     }
1961 
1962     clazz->descriptor = NULL;
1963     NULL_AND_FREE(clazz->descriptorAlloc);
1964 
1965     if (clazz->directMethods != NULL) {
1966         Method *directMethods = clazz->directMethods;
1967         int directMethodCount = clazz->directMethodCount;
1968         clazz->directMethods = NULL;
1969         clazz->directMethodCount = -1;
1970         dvmLinearReadWrite(clazz->classLoader, directMethods);
1971         for (i = 0; i < directMethodCount; i++) {
1972             freeMethodInnards(&directMethods[i]);
1973         }
1974         dvmLinearReadOnly(clazz->classLoader, directMethods);
1975         dvmLinearFree(clazz->classLoader, directMethods);
1976     }
1977     if (clazz->virtualMethods != NULL) {
1978         Method *virtualMethods = clazz->virtualMethods;
1979         int virtualMethodCount = clazz->virtualMethodCount;
1980         clazz->virtualMethodCount = -1;
1981         clazz->virtualMethods = NULL;
1982         dvmLinearReadWrite(clazz->classLoader, virtualMethods);
1983         for (i = 0; i < virtualMethodCount; i++) {
1984             freeMethodInnards(&virtualMethods[i]);
1985         }
1986         dvmLinearReadOnly(clazz->classLoader, virtualMethods);
1987         dvmLinearFree(clazz->classLoader, virtualMethods);
1988     }
1989 
1990     InitiatingLoaderList *loaderList = dvmGetInitiatingLoaderList(clazz);
1991     loaderList->initiatingLoaderCount = -1;
1992     NULL_AND_FREE(loaderList->initiatingLoaders);
1993 
1994     clazz->interfaceCount = -1;
1995     NULL_AND_LINEAR_FREE(clazz->interfaces);
1996 
1997     clazz->iftableCount = -1;
1998     NULL_AND_LINEAR_FREE(clazz->iftable);
1999 
2000     clazz->ifviPoolCount = -1;
2001     NULL_AND_LINEAR_FREE(clazz->ifviPool);
2002 
2003     clazz->sfieldCount = -1;
2004     NULL_AND_FREE(clazz->sfields);
2005 
2006     clazz->ifieldCount = -1;
2007     NULL_AND_LINEAR_FREE(clazz->ifields);
2008 
2009 #undef NULL_AND_FREE
2010 #undef NULL_AND_LINEAR_FREE
2011 }
2012 
2013 /*
2014  * Free anything in a Method that was allocated on the system heap.
2015  *
2016  * The containing class is largely torn down by this point.
2017  */
freeMethodInnards(Method * meth)2018 static void freeMethodInnards(Method* meth)
2019 {
2020 #if 0
2021     free(meth->exceptions);
2022     free(meth->lines);
2023     free(meth->locals);
2024 #endif
2025 
2026     /*
2027      * Some register maps are allocated on the heap, either because of late
2028      * verification or because we're caching an uncompressed form.
2029      */
2030     const RegisterMap* pMap = meth->registerMap;
2031     if (pMap != NULL && dvmRegisterMapGetOnHeap(pMap)) {
2032         dvmFreeRegisterMap((RegisterMap*) pMap);
2033         meth->registerMap = NULL;
2034     }
2035 
2036     /*
2037      * We may have copied the instructions.
2038      */
2039     if (IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) {
2040         DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth);
2041         dvmLinearFree(meth->clazz->classLoader, methodDexCode);
2042     }
2043 }
2044 
2045 /*
2046  * Clone a Method, making new copies of anything that will be freed up
2047  * by freeMethodInnards().  This is used for "miranda" methods.
2048  */
cloneMethod(Method * dst,const Method * src)2049 static void cloneMethod(Method* dst, const Method* src)
2050 {
2051     if (src->registerMap != NULL) {
2052         LOGE("GLITCH: only expected abstract methods here\n");
2053         LOGE("        cloning %s.%s\n", src->clazz->descriptor, src->name);
2054         dvmAbort();
2055     }
2056     memcpy(dst, src, sizeof(Method));
2057 }
2058 
2059 /*
2060  * Pull the interesting pieces out of a DexMethod.
2061  *
2062  * The DEX file isn't going anywhere, so we don't need to make copies of
2063  * the code area.
2064  */
loadMethodFromDex(ClassObject * clazz,const DexMethod * pDexMethod,Method * meth)2065 static void loadMethodFromDex(ClassObject* clazz, const DexMethod* pDexMethod,
2066     Method* meth)
2067 {
2068     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2069     const DexMethodId* pMethodId;
2070     const DexCode* pDexCode;
2071 
2072     pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx);
2073 
2074     meth->name = dexStringById(pDexFile, pMethodId->nameIdx);
2075     dexProtoSetFromMethodId(&meth->prototype, pDexFile, pMethodId);
2076     meth->shorty = dexProtoGetShorty(&meth->prototype);
2077     meth->accessFlags = pDexMethod->accessFlags;
2078     meth->clazz = clazz;
2079     meth->jniArgInfo = 0;
2080 
2081     if (dvmCompareNameDescriptorAndMethod("finalize", "()V", meth) == 0) {
2082         SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE);
2083     }
2084 
2085     pDexCode = dexGetCode(pDexFile, pDexMethod);
2086     if (pDexCode != NULL) {
2087         /* integer constants, copy over for faster access */
2088         meth->registersSize = pDexCode->registersSize;
2089         meth->insSize = pDexCode->insSize;
2090         meth->outsSize = pDexCode->outsSize;
2091 
2092         /* pointer to code area */
2093         meth->insns = pDexCode->insns;
2094     } else {
2095         /*
2096          * We don't have a DexCode block, but we still want to know how
2097          * much space is needed for the arguments (so we don't have to
2098          * compute it later).  We also take this opportunity to compute
2099          * JNI argument info.
2100          *
2101          * We do this for abstract methods as well, because we want to
2102          * be able to substitute our exception-throwing "stub" in.
2103          */
2104         int argsSize = dvmComputeMethodArgsSize(meth);
2105         if (!dvmIsStaticMethod(meth))
2106             argsSize++;
2107         meth->registersSize = meth->insSize = argsSize;
2108         assert(meth->outsSize == 0);
2109         assert(meth->insns == NULL);
2110 
2111         if (dvmIsNativeMethod(meth)) {
2112             meth->nativeFunc = dvmResolveNativeMethod;
2113             meth->jniArgInfo = computeJniArgInfo(&meth->prototype);
2114         }
2115     }
2116 }
2117 
2118 /*
2119  * We usually map bytecode directly out of the DEX file, which is mapped
2120  * shared read-only.  If we want to be able to modify it, we have to make
2121  * a new copy.
2122  *
2123  * Once copied, the code will be in the LinearAlloc region, which may be
2124  * marked read-only.
2125  *
2126  * The bytecode instructions are embedded inside a DexCode structure, so we
2127  * need to copy all of that.  (The dvmGetMethodCode function backs up the
2128  * instruction pointer to find the start of the DexCode.)
2129  */
dvmMakeCodeReadWrite(Method * meth)2130 void dvmMakeCodeReadWrite(Method* meth)
2131 {
2132     DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth);
2133 
2134     if (IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) {
2135         dvmLinearReadWrite(meth->clazz->classLoader, methodDexCode);
2136         return;
2137     }
2138 
2139     assert(!dvmIsNativeMethod(meth) && !dvmIsAbstractMethod(meth));
2140 
2141     size_t dexCodeSize = dexGetDexCodeSize(methodDexCode);
2142     LOGD("Making a copy of %s.%s code (%d bytes)\n",
2143         meth->clazz->descriptor, meth->name, dexCodeSize);
2144 
2145     DexCode* newCode =
2146         (DexCode*) dvmLinearAlloc(meth->clazz->classLoader, dexCodeSize);
2147     memcpy(newCode, methodDexCode, dexCodeSize);
2148 
2149     meth->insns = newCode->insns;
2150     SET_METHOD_FLAG(meth, METHOD_ISWRITABLE);
2151 }
2152 
2153 /*
2154  * Mark the bytecode read-only.
2155  *
2156  * If the contents of the DexCode haven't actually changed, we could revert
2157  * to the original shared page.
2158  */
dvmMakeCodeReadOnly(Method * meth)2159 void dvmMakeCodeReadOnly(Method* meth)
2160 {
2161     DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth);
2162     LOGV("+++ marking %p read-only\n", methodDexCode);
2163     dvmLinearReadOnly(meth->clazz->classLoader, methodDexCode);
2164 }
2165 
2166 
2167 /*
2168  * jniArgInfo (32-bit int) layout:
2169  *   SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH
2170  *
2171  *   S - if set, do things the hard way (scan the signature)
2172  *   R - return-type enumeration
2173  *   H - target-specific hints
2174  *
2175  * This info is used at invocation time by dvmPlatformInvoke.  In most
2176  * cases, the target-specific hints allow dvmPlatformInvoke to avoid
2177  * having to fully parse the signature.
2178  *
2179  * The return-type bits are always set, even if target-specific hint bits
2180  * are unavailable.
2181  */
computeJniArgInfo(const DexProto * proto)2182 static int computeJniArgInfo(const DexProto* proto)
2183 {
2184     const char* sig = dexProtoGetShorty(proto);
2185     int returnType, padFlags, jniArgInfo;
2186     char sigByte;
2187     int stackOffset, padMask;
2188     u4 hints;
2189 
2190     /* The first shorty character is the return type. */
2191     switch (*(sig++)) {
2192     case 'V':
2193         returnType = DALVIK_JNI_RETURN_VOID;
2194         break;
2195     case 'F':
2196         returnType = DALVIK_JNI_RETURN_FLOAT;
2197         break;
2198     case 'D':
2199         returnType = DALVIK_JNI_RETURN_DOUBLE;
2200         break;
2201     case 'J':
2202         returnType = DALVIK_JNI_RETURN_S8;
2203         break;
2204     case 'Z':
2205     case 'B':
2206         returnType = DALVIK_JNI_RETURN_S1;
2207         break;
2208     case 'C':
2209         returnType = DALVIK_JNI_RETURN_U2;
2210         break;
2211     case 'S':
2212         returnType = DALVIK_JNI_RETURN_S2;
2213         break;
2214     default:
2215         returnType = DALVIK_JNI_RETURN_S4;
2216         break;
2217     }
2218 
2219     jniArgInfo = returnType << DALVIK_JNI_RETURN_SHIFT;
2220 
2221     hints = dvmPlatformInvokeHints(proto);
2222 
2223     if (hints & DALVIK_JNI_NO_ARG_INFO) {
2224         jniArgInfo |= DALVIK_JNI_NO_ARG_INFO;
2225     } else {
2226         assert((hints & DALVIK_JNI_RETURN_MASK) == 0);
2227         jniArgInfo |= hints;
2228     }
2229 
2230     return jniArgInfo;
2231 }
2232 
2233 /*
2234  * Load information about a static field.
2235  *
2236  * This also "prepares" static fields by initializing them
2237  * to their "standard default values".
2238  */
loadSFieldFromDex(ClassObject * clazz,const DexField * pDexSField,StaticField * sfield)2239 static void loadSFieldFromDex(ClassObject* clazz,
2240     const DexField* pDexSField, StaticField* sfield)
2241 {
2242     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2243     const DexFieldId* pFieldId;
2244 
2245     pFieldId = dexGetFieldId(pDexFile, pDexSField->fieldIdx);
2246 
2247     sfield->field.clazz = clazz;
2248     sfield->field.name = dexStringById(pDexFile, pFieldId->nameIdx);
2249     sfield->field.signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
2250     sfield->field.accessFlags = pDexSField->accessFlags;
2251 
2252     /* Static object field values are set to "standard default values"
2253      * (null or 0) until the class is initialized.  We delay loading
2254      * constant values from the class until that time.
2255      */
2256     //sfield->value.j = 0;
2257     assert(sfield->value.j == 0LL);     // cleared earlier with calloc
2258 
2259 #ifdef PROFILE_FIELD_ACCESS
2260     sfield->field.gets = sfield->field.puts = 0;
2261 #endif
2262 }
2263 
2264 /*
2265  * Load information about an instance field.
2266  */
loadIFieldFromDex(ClassObject * clazz,const DexField * pDexIField,InstField * ifield)2267 static void loadIFieldFromDex(ClassObject* clazz,
2268     const DexField* pDexIField, InstField* ifield)
2269 {
2270     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2271     const DexFieldId* pFieldId;
2272 
2273     pFieldId = dexGetFieldId(pDexFile, pDexIField->fieldIdx);
2274 
2275     ifield->field.clazz = clazz;
2276     ifield->field.name = dexStringById(pDexFile, pFieldId->nameIdx);
2277     ifield->field.signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
2278     ifield->field.accessFlags = pDexIField->accessFlags;
2279 #ifndef NDEBUG
2280     assert(ifield->byteOffset == 0);    // cleared earlier with calloc
2281     ifield->byteOffset = -1;    // make it obvious if we fail to set later
2282 #endif
2283 
2284 #ifdef PROFILE_FIELD_ACCESS
2285     ifield->field.gets = ifield->field.puts = 0;
2286 #endif
2287 }
2288 
2289 /*
2290  * Cache java.lang.ref.Reference fields and methods.
2291  */
precacheReferenceOffsets(ClassObject * clazz)2292 static bool precacheReferenceOffsets(ClassObject *clazz)
2293 {
2294     Method *meth;
2295     int i;
2296 
2297     /* We trick the GC object scanner by not counting
2298      * java.lang.ref.Reference.referent as an object
2299      * field.  It will get explicitly scanned as part
2300      * of the reference-walking process.
2301      *
2302      * Find the object field named "referent" and put it
2303      * just after the list of object reference fields.
2304      */
2305     dvmLinearReadWrite(clazz->classLoader, clazz->ifields);
2306     for (i = 0; i < clazz->ifieldRefCount; i++) {
2307         InstField *pField = &clazz->ifields[i];
2308         if (strcmp(pField->field.name, "referent") == 0) {
2309             int targetIndex;
2310 
2311             /* Swap this field with the last object field.
2312              */
2313             targetIndex = clazz->ifieldRefCount - 1;
2314             if (i != targetIndex) {
2315                 InstField *swapField = &clazz->ifields[targetIndex];
2316                 InstField tmpField;
2317                 int tmpByteOffset;
2318 
2319                 /* It's not currently strictly necessary
2320                  * for the fields to be in byteOffset order,
2321                  * but it's more predictable that way.
2322                  */
2323                 tmpByteOffset = swapField->byteOffset;
2324                 swapField->byteOffset = pField->byteOffset;
2325                 pField->byteOffset = tmpByteOffset;
2326 
2327                 tmpField = *swapField;
2328                 *swapField = *pField;
2329                 *pField = tmpField;
2330             }
2331 
2332             /* One fewer object field (wink wink).
2333              */
2334             clazz->ifieldRefCount--;
2335             i--;        /* don't trip "didn't find it" test if field was last */
2336             break;
2337         }
2338     }
2339     dvmLinearReadOnly(clazz->classLoader, clazz->ifields);
2340     if (i == clazz->ifieldRefCount) {
2341         LOGE("Unable to reorder 'referent' in %s\n", clazz->descriptor);
2342         return false;
2343     }
2344 
2345     /* Cache pretty much everything about Reference so that
2346      * we don't need to call interpreted code when clearing/enqueueing
2347      * references.  This is fragile, so we'll be paranoid.
2348      */
2349     gDvm.classJavaLangRefReference = clazz;
2350 
2351     gDvm.offJavaLangRefReference_referent =
2352         dvmFindFieldOffset(gDvm.classJavaLangRefReference,
2353                 "referent", "Ljava/lang/Object;");
2354     assert(gDvm.offJavaLangRefReference_referent >= 0);
2355 
2356     gDvm.offJavaLangRefReference_queue =
2357         dvmFindFieldOffset(gDvm.classJavaLangRefReference,
2358                 "queue", "Ljava/lang/ref/ReferenceQueue;");
2359     assert(gDvm.offJavaLangRefReference_queue >= 0);
2360 
2361     gDvm.offJavaLangRefReference_queueNext =
2362         dvmFindFieldOffset(gDvm.classJavaLangRefReference,
2363                 "queueNext", "Ljava/lang/ref/Reference;");
2364     assert(gDvm.offJavaLangRefReference_queueNext >= 0);
2365 
2366     gDvm.offJavaLangRefReference_vmData =
2367         dvmFindFieldOffset(gDvm.classJavaLangRefReference,
2368                 "vmData", "I");
2369     assert(gDvm.offJavaLangRefReference_vmData >= 0);
2370 
2371 #if FANCY_REFERENCE_SUBCLASS
2372     meth = dvmFindVirtualMethodByDescriptor(clazz, "clear", "()V");
2373     assert(meth != NULL);
2374     gDvm.voffJavaLangRefReference_clear = meth->methodIndex;
2375 
2376     meth = dvmFindVirtualMethodByDescriptor(clazz, "enqueue", "()Z");
2377     assert(meth != NULL);
2378     gDvm.voffJavaLangRefReference_enqueue = meth->methodIndex;
2379 #else
2380     /* enqueueInternal() is private and thus a direct method. */
2381     meth = dvmFindDirectMethodByDescriptor(clazz, "enqueueInternal", "()Z");
2382     assert(meth != NULL);
2383     gDvm.methJavaLangRefReference_enqueueInternal = meth;
2384 #endif
2385 
2386     return true;
2387 }
2388 
2389 
2390 /*
2391  * Link (prepare and resolve).  Verification is deferred until later.
2392  *
2393  * This converts symbolic references into pointers.  It's independent of
2394  * the source file format.
2395  *
2396  * If "classesResolved" is false, we assume that superclassIdx and
2397  * interfaces[] are holding class reference indices rather than pointers.
2398  * The class references will be resolved during link.  (This is done when
2399  * loading from DEX to avoid having to create additional storage to pass
2400  * the indices around.)
2401  *
2402  * Returns "false" with an exception pending on failure.
2403  */
dvmLinkClass(ClassObject * clazz,bool classesResolved)2404 bool dvmLinkClass(ClassObject* clazz, bool classesResolved)
2405 {
2406     u4 superclassIdx = 0;
2407     bool okay = false;
2408     bool resolve_okay;
2409     int numInterfacesResolved = 0;
2410     int i;
2411 
2412     if (gDvm.verboseClass)
2413         LOGV("CLASS: linking '%s'...\n", clazz->descriptor);
2414 
2415     /* "Resolve" the class.
2416      *
2417      * At this point, clazz's reference fields contain Dex
2418      * file indices instead of direct object references.
2419      * We need to translate those indices into real references,
2420      * while making sure that the GC doesn't sweep any of
2421      * the referenced objects.
2422      *
2423      * The GC will avoid scanning this object as long as
2424      * clazz->obj.clazz is gDvm.unlinkedJavaLangClass.
2425      * Once clazz is ready, we'll replace clazz->obj.clazz
2426      * with gDvm.classJavaLangClass to let the GC know
2427      * to look at it.
2428      */
2429     assert(clazz->obj.clazz == gDvm.unlinkedJavaLangClass);
2430 
2431     /* It's important that we take care of java.lang.Class
2432      * first.  If we were to do this after looking up the
2433      * superclass (below), Class wouldn't be ready when
2434      * java.lang.Object needed it.
2435      *
2436      * Note that we don't set clazz->obj.clazz yet.
2437      */
2438     if (gDvm.classJavaLangClass == NULL) {
2439         if (clazz->classLoader == NULL &&
2440             strcmp(clazz->descriptor, "Ljava/lang/Class;") == 0)
2441         {
2442             gDvm.classJavaLangClass = clazz;
2443         } else {
2444             gDvm.classJavaLangClass =
2445                 dvmFindSystemClassNoInit("Ljava/lang/Class;");
2446             if (gDvm.classJavaLangClass == NULL) {
2447                 /* should have thrown one */
2448                 assert(dvmCheckException(dvmThreadSelf()));
2449                 goto bail;
2450             }
2451         }
2452     }
2453     assert(gDvm.classJavaLangClass != NULL);
2454 
2455     /*
2456      * Resolve all Dex indices so we can hand the ClassObject
2457      * over to the GC.  If we fail at any point, we need to remove
2458      * any tracked references to avoid leaking memory.
2459      */
2460 
2461     /*
2462      * All classes have a direct superclass, except for java/lang/Object.
2463      */
2464     if (!classesResolved) {
2465         superclassIdx = (u4) clazz->super;          /* unpack temp store */
2466         clazz->super = NULL;
2467     }
2468     if (strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0) {
2469         assert(!classesResolved);
2470         if (superclassIdx != kDexNoIndex) {
2471             /* TODO: is this invariant true for all java/lang/Objects,
2472              * regardless of the class loader?  For now, assume it is.
2473              */
2474             dvmThrowException("Ljava/lang/ClassFormatError;",
2475                 "java.lang.Object has a superclass");
2476             goto bail;
2477         }
2478 
2479         /* Don't finalize objects whose classes use the
2480          * default (empty) Object.finalize().
2481          */
2482         CLEAR_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE);
2483     } else {
2484         if (!classesResolved) {
2485             if (superclassIdx == kDexNoIndex) {
2486                 dvmThrowException("Ljava/lang/LinkageError;",
2487                     "no superclass defined");
2488                 goto bail;
2489             }
2490             clazz->super = dvmResolveClass(clazz, superclassIdx, false);
2491             if (clazz->super == NULL) {
2492                 assert(dvmCheckException(dvmThreadSelf()));
2493                 if (gDvm.optimizing) {
2494                     /* happens with "external" libs */
2495                     LOGV("Unable to resolve superclass of %s (%d)\n",
2496                         clazz->descriptor, superclassIdx);
2497                 } else {
2498                     LOGW("Unable to resolve superclass of %s (%d)\n",
2499                         clazz->descriptor, superclassIdx);
2500                 }
2501                 goto bail;
2502             }
2503         }
2504         /* verify */
2505         if (dvmIsFinalClass(clazz->super)) {
2506             LOGW("Superclass of '%s' is final '%s'\n",
2507                 clazz->descriptor, clazz->super->descriptor);
2508             dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
2509                 "superclass is final");
2510             goto bail;
2511         } else if (dvmIsInterfaceClass(clazz->super)) {
2512             LOGW("Superclass of '%s' is interface '%s'\n",
2513                 clazz->descriptor, clazz->super->descriptor);
2514             dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
2515                 "superclass is an interface");
2516             goto bail;
2517         } else if (!dvmCheckClassAccess(clazz, clazz->super)) {
2518             LOGW("Superclass of '%s' (%s) is not accessible\n",
2519                 clazz->descriptor, clazz->super->descriptor);
2520             dvmThrowException("Ljava/lang/IllegalAccessError;",
2521                 "superclass not accessible");
2522             goto bail;
2523         }
2524 
2525         /* Don't let the GC reclaim the superclass.
2526          * TODO: shouldn't be needed; remove when things stabilize
2527          */
2528         dvmAddTrackedAlloc((Object *)clazz->super, NULL);
2529 
2530         /* Inherit finalizability from the superclass.  If this
2531          * class also overrides finalize(), its CLASS_ISFINALIZABLE
2532          * bit will already be set.
2533          */
2534         if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISFINALIZABLE)) {
2535             SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE);
2536         }
2537 
2538         /* See if this class descends from java.lang.Reference
2539          * and set the class flags appropriately.
2540          */
2541         if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISREFERENCE)) {
2542             u4 superRefFlags;
2543 
2544             /* We've already determined the reference type of this
2545              * inheritance chain.  Inherit reference-ness from the superclass.
2546              */
2547             superRefFlags = GET_CLASS_FLAG_GROUP(clazz->super,
2548                     CLASS_ISREFERENCE |
2549                     CLASS_ISWEAKREFERENCE |
2550                     CLASS_ISPHANTOMREFERENCE);
2551             SET_CLASS_FLAG(clazz, superRefFlags);
2552         } else if (clazz->classLoader == NULL &&
2553                 clazz->super->classLoader == NULL &&
2554                 strcmp(clazz->super->descriptor,
2555                        "Ljava/lang/ref/Reference;") == 0)
2556         {
2557             u4 refFlags;
2558 
2559             /* This class extends Reference, which means it should
2560              * be one of the magic Soft/Weak/PhantomReference classes.
2561              */
2562             refFlags = CLASS_ISREFERENCE;
2563             if (strcmp(clazz->descriptor,
2564                        "Ljava/lang/ref/SoftReference;") == 0)
2565             {
2566                 /* Only CLASS_ISREFERENCE is set for soft references.
2567                  */
2568             } else if (strcmp(clazz->descriptor,
2569                        "Ljava/lang/ref/WeakReference;") == 0)
2570             {
2571                 refFlags |= CLASS_ISWEAKREFERENCE;
2572             } else if (strcmp(clazz->descriptor,
2573                        "Ljava/lang/ref/PhantomReference;") == 0)
2574             {
2575                 refFlags |= CLASS_ISPHANTOMREFERENCE;
2576             } else {
2577                 /* No-one else is allowed to inherit directly
2578                  * from Reference.
2579                  */
2580 //xxx is this the right exception?  better than an assertion.
2581                 dvmThrowException("Ljava/lang/LinkageError;",
2582                     "illegal inheritance from Reference");
2583                 goto bail;
2584             }
2585 
2586             /* The class should not have any reference bits set yet.
2587              */
2588             assert(GET_CLASS_FLAG_GROUP(clazz,
2589                     CLASS_ISREFERENCE |
2590                     CLASS_ISWEAKREFERENCE |
2591                     CLASS_ISPHANTOMREFERENCE) == 0);
2592 
2593             SET_CLASS_FLAG(clazz, refFlags);
2594         }
2595     }
2596 
2597     if (!classesResolved && clazz->interfaceCount > 0) {
2598         /*
2599          * Resolve the interfaces implemented directly by this class.  We
2600          * stuffed the class index into the interface pointer slot.
2601          */
2602         dvmLinearReadWrite(clazz->classLoader, clazz->interfaces);
2603         for (i = 0; i < clazz->interfaceCount; i++) {
2604             u4 interfaceIdx;
2605 
2606             interfaceIdx = (u4) clazz->interfaces[i];   /* unpack temp store */
2607             assert(interfaceIdx != kDexNoIndex);
2608 
2609             clazz->interfaces[i] = dvmResolveClass(clazz, interfaceIdx, false);
2610             if (clazz->interfaces[i] == NULL) {
2611                 const DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2612 
2613                 assert(dvmCheckException(dvmThreadSelf()));
2614                 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
2615 
2616                 const char* classDescriptor;
2617                 classDescriptor = dexStringByTypeIdx(pDexFile, interfaceIdx);
2618                 if (gDvm.optimizing) {
2619                     /* happens with "external" libs */
2620                     LOGV("Failed resolving %s interface %d '%s'\n",
2621                         clazz->descriptor, interfaceIdx, classDescriptor);
2622                 } else {
2623                     LOGI("Failed resolving %s interface %d '%s'\n",
2624                         clazz->descriptor, interfaceIdx, classDescriptor);
2625                 }
2626                 goto bail_during_resolve;
2627             }
2628 
2629             /* are we allowed to implement this interface? */
2630             if (!dvmCheckClassAccess(clazz, clazz->interfaces[i])) {
2631                 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
2632                 LOGW("Interface '%s' is not accessible to '%s'\n",
2633                     clazz->interfaces[i]->descriptor, clazz->descriptor);
2634                 dvmThrowException("Ljava/lang/IllegalAccessError;",
2635                     "interface not accessible");
2636                 goto bail_during_resolve;
2637             }
2638 
2639             /* Don't let the GC reclaim the interface class.
2640              * TODO: shouldn't be needed; remove when things stabilize
2641              */
2642             dvmAddTrackedAlloc((Object *)clazz->interfaces[i], NULL);
2643             numInterfacesResolved++;
2644 
2645             LOGVV("+++  found interface '%s'\n",
2646                 clazz->interfaces[i]->descriptor);
2647         }
2648         dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
2649     }
2650 
2651     /*
2652      * The ClassObject is now in a GC-able state.  We let the GC
2653      * realize this by punching in the real class type, which is
2654      * always java.lang.Class.
2655      *
2656      * After this line, clazz will be fair game for the GC.
2657      * Every field that the GC will look at must now be valid:
2658      * - clazz->super
2659      * - class->classLoader
2660      * - clazz->sfields
2661      * - clazz->interfaces
2662      */
2663     clazz->obj.clazz = gDvm.classJavaLangClass;
2664 
2665     if (false) {
2666 bail_during_resolve:
2667         resolve_okay = false;
2668     } else {
2669         resolve_okay = true;
2670     }
2671 
2672     /*
2673      * Now that the GC can scan the ClassObject, we can let
2674      * go of the explicit references we were holding onto.
2675      *
2676      * Either that or we failed, in which case we need to
2677      * release the references so we don't leak memory.
2678      */
2679     if (clazz->super != NULL) {
2680         dvmReleaseTrackedAlloc((Object *)clazz->super, NULL);
2681     }
2682     for (i = 0; i < numInterfacesResolved; i++) {
2683         dvmReleaseTrackedAlloc((Object *)clazz->interfaces[i], NULL);
2684     }
2685 
2686     if (!resolve_okay) {
2687         //LOGW("resolve_okay is false\n");
2688         goto bail;
2689     }
2690 
2691     /*
2692      * Populate vtable.
2693      */
2694     if (dvmIsInterfaceClass(clazz)) {
2695         /* no vtable; just set the method indices */
2696         int count = clazz->virtualMethodCount;
2697 
2698         if (count != (u2) count) {
2699             LOGE("Too many methods (%d) in interface '%s'\n", count,
2700                  clazz->descriptor);
2701             goto bail;
2702         }
2703 
2704         dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
2705 
2706         for (i = 0; i < count; i++)
2707             clazz->virtualMethods[i].methodIndex = (u2) i;
2708 
2709         dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
2710     } else {
2711         if (!createVtable(clazz)) {
2712             LOGW("failed creating vtable\n");
2713             goto bail;
2714         }
2715     }
2716 
2717     /*
2718      * Populate interface method tables.  Can alter the vtable.
2719      */
2720     if (!createIftable(clazz))
2721         goto bail;
2722 
2723     /*
2724      * Insert special-purpose "stub" method implementations.
2725      */
2726     if (!insertMethodStubs(clazz))
2727         goto bail;
2728 
2729     /*
2730      * Compute instance field offsets and, hence, the size of the object.
2731      */
2732     if (!computeFieldOffsets(clazz))
2733         goto bail;
2734 
2735     /*
2736      * Cache fields and methods from java/lang/ref/Reference and
2737      * java/lang/Class.  This has to happen after computeFieldOffsets().
2738      */
2739     if (clazz->classLoader == NULL) {
2740         if (strcmp(clazz->descriptor, "Ljava/lang/ref/Reference;") == 0) {
2741             if (!precacheReferenceOffsets(clazz)) {
2742                 LOGE("failed pre-caching Reference offsets\n");
2743                 dvmThrowException("Ljava/lang/InternalError;", NULL);
2744                 goto bail;
2745             }
2746         } else if (clazz == gDvm.classJavaLangClass) {
2747             gDvm.offJavaLangClass_pd = dvmFindFieldOffset(clazz, "pd",
2748                 "Ljava/security/ProtectionDomain;");
2749             if (gDvm.offJavaLangClass_pd <= 0) {
2750                 LOGE("ERROR: unable to find 'pd' field in Class\n");
2751                 dvmAbort();     /* we're not going to get much farther */
2752                 //goto bail;
2753             }
2754         }
2755     }
2756 
2757     /*
2758      * Done!
2759      */
2760     if (IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED))
2761         clazz->status = CLASS_VERIFIED;
2762     else
2763         clazz->status = CLASS_RESOLVED;
2764     okay = true;
2765     if (gDvm.verboseClass)
2766         LOGV("CLASS: linked '%s'\n", clazz->descriptor);
2767 
2768     /*
2769      * We send CLASS_PREPARE events to the debugger from here.  The
2770      * definition of "preparation" is creating the static fields for a
2771      * class and initializing them to the standard default values, but not
2772      * executing any code (that comes later, during "initialization").
2773      *
2774      * We did the static prep in loadSFieldFromDex() while loading the class.
2775      *
2776      * The class has been prepared and resolved but possibly not yet verified
2777      * at this point.
2778      */
2779     if (gDvm.debuggerActive) {
2780         dvmDbgPostClassPrepare(clazz);
2781     }
2782 
2783 bail:
2784     if (!okay) {
2785         clazz->status = CLASS_ERROR;
2786         if (!dvmCheckException(dvmThreadSelf())) {
2787             dvmThrowException("Ljava/lang/VirtualMachineError;", NULL);
2788         }
2789     }
2790     return okay;
2791 }
2792 
2793 /*
2794  * Create the virtual method table.
2795  *
2796  * The top part of the table is a copy of the table from our superclass,
2797  * with our local methods overriding theirs.  The bottom part of the table
2798  * has any new methods we defined.
2799  */
createVtable(ClassObject * clazz)2800 static bool createVtable(ClassObject* clazz)
2801 {
2802     bool result = false;
2803     int maxCount;
2804     int i;
2805 
2806     if (clazz->super != NULL) {
2807         //LOGI("SUPER METHODS %d %s->%s\n", clazz->super->vtableCount,
2808         //    clazz->descriptor, clazz->super->descriptor);
2809     }
2810 
2811     /* the virtual methods we define, plus the superclass vtable size */
2812     maxCount = clazz->virtualMethodCount;
2813     if (clazz->super != NULL) {
2814         maxCount += clazz->super->vtableCount;
2815     } else {
2816         /* TODO: is this invariant true for all java/lang/Objects,
2817          * regardless of the class loader?  For now, assume it is.
2818          */
2819         assert(strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0);
2820     }
2821     //LOGD("+++ max vmethods for '%s' is %d\n", clazz->descriptor, maxCount);
2822 
2823     /*
2824      * Over-allocate the table, then realloc it down if necessary.  So
2825      * long as we don't allocate anything in between we won't cause
2826      * fragmentation, and reducing the size should be unlikely to cause
2827      * a buffer copy.
2828      */
2829     dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
2830     clazz->vtable = (Method**) dvmLinearAlloc(clazz->classLoader,
2831                         sizeof(Method*) * maxCount);
2832     if (clazz->vtable == NULL)
2833         goto bail;
2834 
2835     if (clazz->super != NULL) {
2836         int actualCount;
2837 
2838         memcpy(clazz->vtable, clazz->super->vtable,
2839             sizeof(*(clazz->vtable)) * clazz->super->vtableCount);
2840         actualCount = clazz->super->vtableCount;
2841 
2842         /*
2843          * See if any of our virtual methods override the superclass.
2844          */
2845         for (i = 0; i < clazz->virtualMethodCount; i++) {
2846             Method* localMeth = &clazz->virtualMethods[i];
2847             int si;
2848 
2849             for (si = 0; si < clazz->super->vtableCount; si++) {
2850                 Method* superMeth = clazz->vtable[si];
2851 
2852                 if (dvmCompareMethodNamesAndProtos(localMeth, superMeth) == 0)
2853                 {
2854                     /* verify */
2855                     if (dvmIsFinalMethod(superMeth)) {
2856                         LOGW("Method %s.%s overrides final %s.%s\n",
2857                             localMeth->clazz->descriptor, localMeth->name,
2858                             superMeth->clazz->descriptor, superMeth->name);
2859                         goto bail;
2860                     }
2861                     clazz->vtable[si] = localMeth;
2862                     localMeth->methodIndex = (u2) si;
2863                     //LOGV("+++   override %s.%s (slot %d)\n",
2864                     //    clazz->descriptor, localMeth->name, si);
2865                     break;
2866                 }
2867             }
2868 
2869             if (si == clazz->super->vtableCount) {
2870                 /* not an override, add to end */
2871                 clazz->vtable[actualCount] = localMeth;
2872                 localMeth->methodIndex = (u2) actualCount;
2873                 actualCount++;
2874 
2875                 //LOGV("+++   add method %s.%s\n",
2876                 //    clazz->descriptor, localMeth->name);
2877             }
2878         }
2879 
2880         if (actualCount != (u2) actualCount) {
2881             LOGE("Too many methods (%d) in class '%s'\n", actualCount,
2882                  clazz->descriptor);
2883             goto bail;
2884         }
2885 
2886         assert(actualCount <= maxCount);
2887 
2888         if (actualCount < maxCount) {
2889             assert(clazz->vtable != NULL);
2890             dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
2891             clazz->vtable = dvmLinearRealloc(clazz->classLoader, clazz->vtable,
2892                 sizeof(*(clazz->vtable)) * actualCount);
2893             if (clazz->vtable == NULL) {
2894                 LOGE("vtable realloc failed\n");
2895                 goto bail;
2896             } else {
2897                 LOGVV("+++  reduced vtable from %d to %d\n",
2898                     maxCount, actualCount);
2899             }
2900         }
2901 
2902         clazz->vtableCount = actualCount;
2903     } else {
2904         /* java/lang/Object case */
2905         int count = clazz->virtualMethodCount;
2906         if (count != (u2) count) {
2907             LOGE("Too many methods (%d) in base class '%s'\n", count,
2908                  clazz->descriptor);
2909             goto bail;
2910         }
2911 
2912         for (i = 0; i < count; i++) {
2913             clazz->vtable[i] = &clazz->virtualMethods[i];
2914             clazz->virtualMethods[i].methodIndex = (u2) i;
2915         }
2916         clazz->vtableCount = clazz->virtualMethodCount;
2917     }
2918 
2919     result = true;
2920 
2921 bail:
2922     dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
2923     dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
2924     return result;
2925 }
2926 
2927 /*
2928  * Create and populate "iftable".
2929  *
2930  * The set of interfaces we support is the combination of the interfaces
2931  * we implement directly and those implemented by our superclass.  Each
2932  * interface can have one or more "superinterfaces", which we must also
2933  * support.  For speed we flatten the tree out.
2934  *
2935  * We might be able to speed this up when there are lots of interfaces
2936  * by merge-sorting the class pointers and binary-searching when removing
2937  * duplicates.  We could also drop the duplicate removal -- it's only
2938  * there to reduce the memory footprint.
2939  *
2940  * Because of "Miranda methods", this may reallocate clazz->virtualMethods.
2941  *
2942  * Returns "true" on success.
2943  */
createIftable(ClassObject * clazz)2944 static bool createIftable(ClassObject* clazz)
2945 {
2946     bool result = false;
2947     bool zapIftable = false;
2948     bool zapVtable = false;
2949     bool zapIfvipool = false;
2950     int ifCount, superIfCount, idx;
2951     int i;
2952 
2953     if (clazz->super != NULL)
2954         superIfCount = clazz->super->iftableCount;
2955     else
2956         superIfCount = 0;
2957 
2958     ifCount = superIfCount;
2959     ifCount += clazz->interfaceCount;
2960     for (i = 0; i < clazz->interfaceCount; i++)
2961         ifCount += clazz->interfaces[i]->iftableCount;
2962 
2963     LOGVV("INTF: class '%s' direct w/supra=%d super=%d total=%d\n",
2964         clazz->descriptor, ifCount - superIfCount, superIfCount, ifCount);
2965 
2966     if (ifCount == 0) {
2967         assert(clazz->iftableCount == 0);
2968         assert(clazz->iftable == NULL);
2969         result = true;
2970         goto bail;
2971     }
2972 
2973     /*
2974      * Create a table with enough space for all interfaces, and copy the
2975      * superclass' table in.
2976      */
2977     clazz->iftable = (InterfaceEntry*) dvmLinearAlloc(clazz->classLoader,
2978                         sizeof(InterfaceEntry) * ifCount);
2979     zapIftable = true;
2980     memset(clazz->iftable, 0x00, sizeof(InterfaceEntry) * ifCount);
2981     if (superIfCount != 0) {
2982         memcpy(clazz->iftable, clazz->super->iftable,
2983             sizeof(InterfaceEntry) * superIfCount);
2984     }
2985 
2986     /*
2987      * Create a flattened interface hierarchy of our immediate interfaces.
2988      */
2989     idx = superIfCount;
2990 
2991     for (i = 0; i < clazz->interfaceCount; i++) {
2992         ClassObject* interf;
2993         int j;
2994 
2995         interf = clazz->interfaces[i];
2996         assert(interf != NULL);
2997 
2998         /* make sure this is still an interface class */
2999         if (!dvmIsInterfaceClass(interf)) {
3000             LOGW("Class '%s' implements non-interface '%s'\n",
3001                 clazz->descriptor, interf->descriptor);
3002             dvmThrowExceptionWithClassMessage(
3003                 "Ljava/lang/IncompatibleClassChangeError;",
3004                 clazz->descriptor);
3005             goto bail;
3006         }
3007 
3008         /* add entry for this interface */
3009         clazz->iftable[idx++].clazz = interf;
3010 
3011         /* add entries for the interface's superinterfaces */
3012         for (j = 0; j < interf->iftableCount; j++) {
3013             clazz->iftable[idx++].clazz = interf->iftable[j].clazz;
3014         }
3015     }
3016 
3017     assert(idx == ifCount);
3018 
3019     if (false) {
3020         /*
3021          * Remove anything redundant from our recent additions.  Note we have
3022          * to traverse the recent adds when looking for duplicates, because
3023          * it's possible the recent additions are self-redundant.  This
3024          * reduces the memory footprint of classes with lots of inherited
3025          * interfaces.
3026          *
3027          * (I don't know if this will cause problems later on when we're trying
3028          * to find a static field.  It looks like the proper search order is
3029          * (1) current class, (2) interfaces implemented by current class,
3030          * (3) repeat with superclass.  A field implemented by an interface
3031          * and by a superclass might come out wrong if the superclass also
3032          * implements the interface.  The javac compiler will reject the
3033          * situation as ambiguous, so the concern is somewhat artificial.)
3034          *
3035          * UPDATE: this makes ReferenceType.Interfaces difficult to implement,
3036          * because it wants to return just the interfaces declared to be
3037          * implemented directly by the class.  I'm excluding this code for now.
3038          */
3039         for (i = superIfCount; i < ifCount; i++) {
3040             int j;
3041 
3042             for (j = 0; j < ifCount; j++) {
3043                 if (i == j)
3044                     continue;
3045                 if (clazz->iftable[i].clazz == clazz->iftable[j].clazz) {
3046                     LOGVV("INTF: redundant interface %s in %s\n",
3047                         clazz->iftable[i].clazz->descriptor,
3048                         clazz->descriptor);
3049 
3050                     if (i != ifCount-1)
3051                         memmove(&clazz->iftable[i], &clazz->iftable[i+1],
3052                             (ifCount - i -1) * sizeof(InterfaceEntry));
3053                     ifCount--;
3054                     i--;        // adjust for i++ above
3055                     break;
3056                 }
3057             }
3058         }
3059         LOGVV("INTF: class '%s' nodupes=%d\n", clazz->descriptor, ifCount);
3060     } // if (false)
3061 
3062     clazz->iftableCount = ifCount;
3063 
3064     /*
3065      * If we're an interface, we don't need the vtable pointers, so
3066      * we're done.  If this class doesn't implement an interface that our
3067      * superclass doesn't have, then we again have nothing to do.
3068      */
3069     if (dvmIsInterfaceClass(clazz) || superIfCount == ifCount) {
3070         //dvmDumpClass(clazz, kDumpClassFullDetail);
3071         result = true;
3072         goto bail;
3073     }
3074 
3075     /*
3076      * When we're handling invokeinterface, we probably have an object
3077      * whose type is an interface class rather than a concrete class.  We
3078      * need to convert the method reference into a vtable index.  So, for
3079      * every entry in "iftable", we create a list of vtable indices.
3080      *
3081      * Because our vtable encompasses the superclass vtable, we can use
3082      * the vtable indices from our superclass for all of the interfaces
3083      * that weren't directly implemented by us.
3084      *
3085      * Each entry in "iftable" has a pointer to the start of its set of
3086      * vtable offsets.  The iftable entries in the superclass point to
3087      * storage allocated in the superclass, and the iftable entries added
3088      * for this class point to storage allocated in this class.  "iftable"
3089      * is flat for fast access in a class and all of its subclasses, but
3090      * "ifviPool" is only created for the topmost implementor.
3091      */
3092     int poolSize = 0;
3093     for (i = superIfCount; i < ifCount; i++) {
3094         /*
3095          * Note it's valid for an interface to have no methods (e.g.
3096          * java/io/Serializable).
3097          */
3098         LOGVV("INTF: pool: %d from %s\n",
3099             clazz->iftable[i].clazz->virtualMethodCount,
3100             clazz->iftable[i].clazz->descriptor);
3101         poolSize += clazz->iftable[i].clazz->virtualMethodCount;
3102     }
3103 
3104     if (poolSize == 0) {
3105         LOGVV("INTF: didn't find any new interfaces with methods\n");
3106         result = true;
3107         goto bail;
3108     }
3109 
3110     clazz->ifviPoolCount = poolSize;
3111     clazz->ifviPool = (int*) dvmLinearAlloc(clazz->classLoader,
3112                         poolSize * sizeof(int*));
3113     zapIfvipool = true;
3114 
3115     /*
3116      * Fill in the vtable offsets for the interfaces that weren't part of
3117      * our superclass.
3118      */
3119     int poolOffset = 0;
3120     Method** mirandaList = NULL;
3121     int mirandaCount = 0, mirandaAlloc = 0;
3122 
3123     for (i = superIfCount; i < ifCount; i++) {
3124         ClassObject* interface;
3125         int methIdx;
3126 
3127         clazz->iftable[i].methodIndexArray = clazz->ifviPool + poolOffset;
3128         interface = clazz->iftable[i].clazz;
3129         poolOffset += interface->virtualMethodCount;    // end here
3130 
3131         /*
3132          * For each method listed in the interface's method list, find the
3133          * matching method in our class's method list.  We want to favor the
3134          * subclass over the superclass, which just requires walking
3135          * back from the end of the vtable.  (This only matters if the
3136          * superclass defines a private method and this class redefines
3137          * it -- otherwise it would use the same vtable slot.  In Dalvik
3138          * those don't end up in the virtual method table, so it shouldn't
3139          * matter which direction we go.  We walk it backward anyway.)
3140          *
3141          *
3142          * Suppose we have the following arrangement:
3143          *   public interface MyInterface
3144          *     public boolean inInterface();
3145          *   public abstract class MirandaAbstract implements MirandaInterface
3146          *     //public abstract boolean inInterface(); // not declared!
3147          *     public boolean inAbstract() { stuff }    // in vtable
3148          *   public class MirandClass extends MirandaAbstract
3149          *     public boolean inInterface() { stuff }
3150          *     public boolean inAbstract() { stuff }    // in vtable
3151          *
3152          * The javac compiler happily compiles MirandaAbstract even though
3153          * it doesn't declare all methods from its interface.  When we try
3154          * to set up a vtable for MirandaAbstract, we find that we don't
3155          * have an slot for inInterface.  To prevent this, we synthesize
3156          * abstract method declarations in MirandaAbstract.
3157          *
3158          * We have to expand vtable and update some things that point at it,
3159          * so we accumulate the method list and do it all at once below.
3160          */
3161         for (methIdx = 0; methIdx < interface->virtualMethodCount; methIdx++) {
3162             Method* imeth = &interface->virtualMethods[methIdx];
3163             int j;
3164 
3165             IF_LOGVV() {
3166                 char* desc = dexProtoCopyMethodDescriptor(&imeth->prototype);
3167                 LOGVV("INTF:  matching '%s' '%s'\n", imeth->name, desc);
3168                 free(desc);
3169             }
3170 
3171             for (j = clazz->vtableCount-1; j >= 0; j--) {
3172                 if (dvmCompareMethodNamesAndProtos(imeth, clazz->vtable[j])
3173                     == 0)
3174                 {
3175                     LOGVV("INTF:   matched at %d\n", j);
3176                     if (!dvmIsPublicMethod(clazz->vtable[j])) {
3177                         LOGW("Implementation of %s.%s is not public\n",
3178                             clazz->descriptor, clazz->vtable[j]->name);
3179                         dvmThrowException("Ljava/lang/IllegalAccessError;",
3180                             "interface implementation not public");
3181                         goto bail;
3182                     }
3183                     clazz->iftable[i].methodIndexArray[methIdx] = j;
3184                     break;
3185                 }
3186             }
3187             if (j < 0) {
3188                 IF_LOGV() {
3189                     char* desc =
3190                         dexProtoCopyMethodDescriptor(&imeth->prototype);
3191                     LOGV("No match for '%s' '%s' in '%s' (creating miranda)\n",
3192                             imeth->name, desc, clazz->descriptor);
3193                     free(desc);
3194                 }
3195                 //dvmThrowException("Ljava/lang/RuntimeException;", "Miranda!");
3196                 //return false;
3197 
3198                 if (mirandaCount == mirandaAlloc) {
3199                     mirandaAlloc += 8;
3200                     if (mirandaList == NULL) {
3201                         mirandaList = dvmLinearAlloc(clazz->classLoader,
3202                                         mirandaAlloc * sizeof(Method*));
3203                     } else {
3204                         dvmLinearReadOnly(clazz->classLoader, mirandaList);
3205                         mirandaList = dvmLinearRealloc(clazz->classLoader,
3206                                 mirandaList, mirandaAlloc * sizeof(Method*));
3207                     }
3208                     assert(mirandaList != NULL);    // mem failed + we leaked
3209                 }
3210 
3211                 /*
3212                  * These may be redundant (e.g. method with same name and
3213                  * signature declared in two interfaces implemented by the
3214                  * same abstract class).  We can squeeze the duplicates
3215                  * out here.
3216                  */
3217                 int mir;
3218                 for (mir = 0; mir < mirandaCount; mir++) {
3219                     if (dvmCompareMethodNamesAndProtos(
3220                             mirandaList[mir], imeth) == 0)
3221                     {
3222                         IF_LOGVV() {
3223                             char* desc = dexProtoCopyMethodDescriptor(
3224                                     &imeth->prototype);
3225                             LOGVV("MIRANDA dupe: %s and %s %s%s\n",
3226                                 mirandaList[mir]->clazz->descriptor,
3227                                 imeth->clazz->descriptor,
3228                                 imeth->name, desc);
3229                             free(desc);
3230                         }
3231                         break;
3232                     }
3233                 }
3234 
3235                 /* point the iftable at a phantom slot index */
3236                 clazz->iftable[i].methodIndexArray[methIdx] =
3237                     clazz->vtableCount + mir;
3238                 LOGVV("MIRANDA: %s points at slot %d\n",
3239                     imeth->name, clazz->vtableCount + mir);
3240 
3241                 /* if non-duplicate among Mirandas, add to Miranda list */
3242                 if (mir == mirandaCount) {
3243                     //LOGV("MIRANDA: holding '%s' in slot %d\n",
3244                     //    imeth->name, mir);
3245                     mirandaList[mirandaCount++] = imeth;
3246                 }
3247             }
3248         }
3249     }
3250 
3251     if (mirandaCount != 0) {
3252         static const int kManyMirandas = 150;   /* arbitrary */
3253         Method* newVirtualMethods;
3254         Method* meth;
3255         int oldMethodCount, oldVtableCount;
3256 
3257         for (i = 0; i < mirandaCount; i++) {
3258             LOGVV("MIRANDA %d: %s.%s\n", i,
3259                 mirandaList[i]->clazz->descriptor, mirandaList[i]->name);
3260         }
3261         if (mirandaCount > kManyMirandas) {
3262             /*
3263              * Some obfuscators like to create an interface with a huge
3264              * pile of methods, declare classes as implementing it, and then
3265              * only define a couple of methods.  This leads to a rather
3266              * massive collection of Miranda methods and a lot of wasted
3267              * space, sometimes enough to blow out the LinearAlloc cap.
3268              */
3269             LOGD("Note: class %s has %d unimplemented (abstract) methods\n",
3270                 clazz->descriptor, mirandaCount);
3271         }
3272 
3273         /*
3274          * We found methods in one or more interfaces for which we do not
3275          * have vtable entries.  We have to expand our virtualMethods
3276          * table (which might be empty) to hold some new entries.
3277          */
3278         if (clazz->virtualMethods == NULL) {
3279             newVirtualMethods = (Method*) dvmLinearAlloc(clazz->classLoader,
3280                 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount));
3281         } else {
3282             //dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
3283             newVirtualMethods = (Method*) dvmLinearRealloc(clazz->classLoader,
3284                 clazz->virtualMethods,
3285                 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount));
3286         }
3287         if (newVirtualMethods != clazz->virtualMethods) {
3288             /*
3289              * Table was moved in memory.  We have to run through the
3290              * vtable and fix the pointers.  The vtable entries might be
3291              * pointing at superclasses, so we flip it around: run through
3292              * all locally-defined virtual methods, and fix their entries
3293              * in the vtable.  (This would get really messy if sub-classes
3294              * had already been loaded.)
3295              *
3296              * Reminder: clazz->virtualMethods and clazz->virtualMethodCount
3297              * hold the virtual methods declared by this class.  The
3298              * method's methodIndex is the vtable index, and is the same
3299              * for all sub-classes (and all super classes in which it is
3300              * defined).  We're messing with these because the Miranda
3301              * stuff makes it look like the class actually has an abstract
3302              * method declaration in it.
3303              */
3304             LOGVV("MIRANDA fixing vtable pointers\n");
3305             dvmLinearReadWrite(clazz->classLoader, clazz->vtable);
3306             Method* meth = newVirtualMethods;
3307             for (i = 0; i < clazz->virtualMethodCount; i++, meth++)
3308                 clazz->vtable[meth->methodIndex] = meth;
3309             dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
3310         }
3311 
3312         oldMethodCount = clazz->virtualMethodCount;
3313         clazz->virtualMethods = newVirtualMethods;
3314         clazz->virtualMethodCount += mirandaCount;
3315 
3316         dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
3317 
3318         /*
3319          * We also have to expand the vtable.
3320          */
3321         assert(clazz->vtable != NULL);
3322         clazz->vtable = (Method**) dvmLinearRealloc(clazz->classLoader,
3323                         clazz->vtable,
3324                         sizeof(Method*) * (clazz->vtableCount + mirandaCount));
3325         if (clazz->vtable == NULL) {
3326             assert(false);
3327             goto bail;
3328         }
3329         zapVtable = true;
3330 
3331         oldVtableCount = clazz->vtableCount;
3332         clazz->vtableCount += mirandaCount;
3333 
3334         /*
3335          * Now we need to create the fake methods.  We clone the abstract
3336          * method definition from the interface and then replace a few
3337          * things.
3338          *
3339          * The Method will be an "abstract native", with nativeFunc set to
3340          * dvmAbstractMethodStub().
3341          */
3342         meth = clazz->virtualMethods + oldMethodCount;
3343         for (i = 0; i < mirandaCount; i++, meth++) {
3344             dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
3345             cloneMethod(meth, mirandaList[i]);
3346             meth->clazz = clazz;
3347             meth->accessFlags |= ACC_MIRANDA;
3348             meth->methodIndex = (u2) (oldVtableCount + i);
3349             dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
3350 
3351             /* point the new vtable entry at the new method */
3352             clazz->vtable[oldVtableCount + i] = meth;
3353         }
3354 
3355         dvmLinearReadOnly(clazz->classLoader, mirandaList);
3356         dvmLinearFree(clazz->classLoader, mirandaList);
3357 
3358     }
3359 
3360     /*
3361      * TODO?
3362      * Sort the interfaces by number of declared methods.  All we really
3363      * want is to get the interfaces with zero methods at the end of the
3364      * list, so that when we walk through the list during invoke-interface
3365      * we don't examine interfaces that can't possibly be useful.
3366      *
3367      * The set will usually be small, so a simple insertion sort works.
3368      *
3369      * We have to be careful not to change the order of two interfaces
3370      * that define the same method.  (Not a problem if we only move the
3371      * zero-method interfaces to the end.)
3372      *
3373      * PROBLEM:
3374      * If we do this, we will no longer be able to identify super vs.
3375      * current class interfaces by comparing clazz->super->iftableCount.  This
3376      * breaks anything that only wants to find interfaces declared directly
3377      * by the class (dvmFindStaticFieldHier, ReferenceType.Interfaces,
3378      * dvmDbgOutputAllInterfaces, etc).  Need to provide a workaround.
3379      *
3380      * We can sort just the interfaces implemented directly by this class,
3381      * but that doesn't seem like it would provide much of an advantage.  I'm
3382      * not sure this is worthwhile.
3383      *
3384      * (This has been made largely obsolete by the interface cache mechanism.)
3385      */
3386 
3387     //dvmDumpClass(clazz);
3388 
3389     result = true;
3390 
3391 bail:
3392     if (zapIftable)
3393         dvmLinearReadOnly(clazz->classLoader, clazz->iftable);
3394     if (zapVtable)
3395         dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
3396     if (zapIfvipool)
3397         dvmLinearReadOnly(clazz->classLoader, clazz->ifviPool);
3398     return result;
3399 }
3400 
3401 
3402 /*
3403  * Provide "stub" implementations for methods without them.
3404  *
3405  * Currently we provide an implementation for all abstract methods that
3406  * throws an AbstractMethodError exception.  This allows us to avoid an
3407  * explicit check for abstract methods in every virtual call.
3408  *
3409  * NOTE: for Miranda methods, the method declaration is a clone of what
3410  * was found in the interface class.  That copy may already have had the
3411  * function pointer filled in, so don't be surprised if it's not NULL.
3412  *
3413  * NOTE: this sets the "native" flag, giving us an "abstract native" method,
3414  * which is nonsensical.  Need to make sure that this doesn't escape the
3415  * VM.  We can either mask it out in reflection calls, or copy "native"
3416  * into the high 16 bits of accessFlags and check that internally.
3417  */
insertMethodStubs(ClassObject * clazz)3418 static bool insertMethodStubs(ClassObject* clazz)
3419 {
3420     dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
3421 
3422     Method* meth;
3423     int i;
3424 
3425     meth = clazz->virtualMethods;
3426     for (i = 0; i < clazz->virtualMethodCount; i++, meth++) {
3427         if (dvmIsAbstractMethod(meth)) {
3428             assert(meth->insns == NULL);
3429             assert(meth->nativeFunc == NULL ||
3430                 meth->nativeFunc == (DalvikBridgeFunc)dvmAbstractMethodStub);
3431 
3432             meth->accessFlags |= ACC_NATIVE;
3433             meth->nativeFunc = (DalvikBridgeFunc) dvmAbstractMethodStub;
3434         }
3435     }
3436 
3437     dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
3438     return true;
3439 }
3440 
3441 
3442 /*
3443  * Swap two instance fields.
3444  */
swapField(InstField * pOne,InstField * pTwo)3445 static inline void swapField(InstField* pOne, InstField* pTwo)
3446 {
3447     InstField swap;
3448 
3449     LOGVV("  --- swap '%s' and '%s'\n", pOne->field.name, pTwo->field.name);
3450     swap = *pOne;
3451     *pOne = *pTwo;
3452     *pTwo = swap;
3453 }
3454 
3455 /*
3456  * Assign instance fields to u4 slots.
3457  *
3458  * The top portion of the instance field area is occupied by the superclass
3459  * fields, the bottom by the fields for this class.
3460  *
3461  * "long" and "double" fields occupy two adjacent slots.  On some
3462  * architectures, 64-bit quantities must be 64-bit aligned, so we need to
3463  * arrange fields (or introduce padding) to ensure this.  We assume the
3464  * fields of the topmost superclass (i.e. Object) are 64-bit aligned, so
3465  * we can just ensure that the offset is "even".  To avoid wasting space,
3466  * we want to move non-reference 32-bit fields into gaps rather than
3467  * creating pad words.
3468  *
3469  * In the worst case we will waste 4 bytes, but because objects are
3470  * allocated on >= 64-bit boundaries, those bytes may well be wasted anyway
3471  * (assuming this is the most-derived class).
3472  *
3473  * Pad words are not represented in the field table, so the field table
3474  * itself does not change size.
3475  *
3476  * The number of field slots determines the size of the object, so we
3477  * set that here too.
3478  *
3479  * This function feels a little more complicated than I'd like, but it
3480  * has the property of moving the smallest possible set of fields, which
3481  * should reduce the time required to load a class.
3482  *
3483  * NOTE: reference fields *must* come first, or precacheReferenceOffsets()
3484  * will break.
3485  */
computeFieldOffsets(ClassObject * clazz)3486 static bool computeFieldOffsets(ClassObject* clazz)
3487 {
3488     int fieldOffset;
3489     int i, j;
3490 
3491     dvmLinearReadWrite(clazz->classLoader, clazz->ifields);
3492 
3493     if (clazz->super != NULL)
3494         fieldOffset = clazz->super->objectSize;
3495     else
3496         fieldOffset = offsetof(DataObject, instanceData);
3497 
3498     LOGVV("--- computeFieldOffsets '%s'\n", clazz->descriptor);
3499 
3500     //LOGI("OFFSETS fieldCount=%d\n", clazz->ifieldCount);
3501     //LOGI("dataobj, instance: %d\n", offsetof(DataObject, instanceData));
3502     //LOGI("classobj, access: %d\n", offsetof(ClassObject, accessFlags));
3503     //LOGI("super=%p, fieldOffset=%d\n", clazz->super, fieldOffset);
3504 
3505     /*
3506      * Start by moving all reference fields to the front.
3507      */
3508     clazz->ifieldRefCount = 0;
3509     j = clazz->ifieldCount - 1;
3510     for (i = 0; i < clazz->ifieldCount; i++) {
3511         InstField* pField = &clazz->ifields[i];
3512         char c = pField->field.signature[0];
3513 
3514         if (c != '[' && c != 'L') {
3515             /* This isn't a reference field; see if any reference fields
3516              * follow this one.  If so, we'll move it to this position.
3517              * (quicksort-style partitioning)
3518              */
3519             while (j > i) {
3520                 InstField* refField = &clazz->ifields[j--];
3521                 char rc = refField->field.signature[0];
3522 
3523                 if (rc == '[' || rc == 'L') {
3524                     /* Here's a reference field that follows at least one
3525                      * non-reference field.  Swap it with the current field.
3526                      * (When this returns, "pField" points to the reference
3527                      * field, and "refField" points to the non-ref field.)
3528                      */
3529                     swapField(pField, refField);
3530 
3531                     /* Fix the signature.
3532                      */
3533                     c = rc;
3534 
3535                     clazz->ifieldRefCount++;
3536                     break;
3537                 }
3538             }
3539             /* We may or may not have swapped a field.
3540              */
3541         } else {
3542             /* This is a reference field.
3543              */
3544             clazz->ifieldRefCount++;
3545         }
3546 
3547         /*
3548          * If we've hit the end of the reference fields, break.
3549          */
3550         if (c != '[' && c != 'L')
3551             break;
3552 
3553         pField->byteOffset = fieldOffset;
3554         fieldOffset += sizeof(u4);
3555         LOGVV("  --- offset1 '%s'=%d\n", pField->field.name,pField->byteOffset);
3556     }
3557 
3558     /*
3559      * Now we want to pack all of the double-wide fields together.  If we're
3560      * not aligned, though, we want to shuffle one 32-bit field into place.
3561      * If we can't find one, we'll have to pad it.
3562      */
3563     if (i != clazz->ifieldCount && (fieldOffset & 0x04) != 0) {
3564         LOGVV("  +++ not aligned\n");
3565 
3566         InstField* pField = &clazz->ifields[i];
3567         char c = pField->field.signature[0];
3568 
3569         if (c != 'J' && c != 'D') {
3570             /*
3571              * The field that comes next is 32-bit, so just advance past it.
3572              */
3573             assert(c != '[' && c != 'L');
3574             pField->byteOffset = fieldOffset;
3575             fieldOffset += sizeof(u4);
3576             i++;
3577             LOGVV("  --- offset2 '%s'=%d\n",
3578                 pField->field.name, pField->byteOffset);
3579         } else {
3580             /*
3581              * Next field is 64-bit, so search for a 32-bit field we can
3582              * swap into it.
3583              */
3584             bool found = false;
3585             j = clazz->ifieldCount - 1;
3586             while (j > i) {
3587                 InstField* singleField = &clazz->ifields[j--];
3588                 char rc = singleField->field.signature[0];
3589 
3590                 if (rc != 'J' && rc != 'D') {
3591                     swapField(pField, singleField);
3592                     //c = rc;
3593                     LOGVV("  +++ swapped '%s' for alignment\n",
3594                         pField->field.name);
3595                     pField->byteOffset = fieldOffset;
3596                     fieldOffset += sizeof(u4);
3597                     LOGVV("  --- offset3 '%s'=%d\n",
3598                         pField->field.name, pField->byteOffset);
3599                     found = true;
3600                     i++;
3601                     break;
3602                 }
3603             }
3604             if (!found) {
3605                 LOGV("  +++ inserting pad field in '%s'\n", clazz->descriptor);
3606                 fieldOffset += sizeof(u4);
3607             }
3608         }
3609     }
3610 
3611     /*
3612      * Alignment is good, shuffle any double-wide fields forward, and
3613      * finish assigning field offsets to all fields.
3614      */
3615     assert(i == clazz->ifieldCount || (fieldOffset & 0x04) == 0);
3616     j = clazz->ifieldCount - 1;
3617     for ( ; i < clazz->ifieldCount; i++) {
3618         InstField* pField = &clazz->ifields[i];
3619         char c = pField->field.signature[0];
3620 
3621         if (c != 'D' && c != 'J') {
3622             /* This isn't a double-wide field; see if any double fields
3623              * follow this one.  If so, we'll move it to this position.
3624              * (quicksort-style partitioning)
3625              */
3626             while (j > i) {
3627                 InstField* doubleField = &clazz->ifields[j--];
3628                 char rc = doubleField->field.signature[0];
3629 
3630                 if (rc == 'D' || rc == 'J') {
3631                     /* Here's a double-wide field that follows at least one
3632                      * non-double field.  Swap it with the current field.
3633                      * (When this returns, "pField" points to the reference
3634                      * field, and "doubleField" points to the non-double field.)
3635                      */
3636                     swapField(pField, doubleField);
3637                     c = rc;
3638 
3639                     break;
3640                 }
3641             }
3642             /* We may or may not have swapped a field.
3643              */
3644         } else {
3645             /* This is a double-wide field, leave it be.
3646              */
3647         }
3648 
3649         pField->byteOffset = fieldOffset;
3650         LOGVV("  --- offset4 '%s'=%d\n", pField->field.name,pField->byteOffset);
3651         fieldOffset += sizeof(u4);
3652         if (c == 'J' || c == 'D')
3653             fieldOffset += sizeof(u4);
3654     }
3655 
3656 #ifndef NDEBUG
3657     /* Make sure that all reference fields appear before
3658      * non-reference fields, and all double-wide fields are aligned.
3659      */
3660     j = 0;  // seen non-ref
3661     for (i = 0; i < clazz->ifieldCount; i++) {
3662         InstField *pField = &clazz->ifields[i];
3663         char c = pField->field.signature[0];
3664 
3665         if (c == 'D' || c == 'J') {
3666             assert((pField->byteOffset & 0x07) == 0);
3667         }
3668 
3669         if (c != '[' && c != 'L') {
3670             if (!j) {
3671                 assert(i == clazz->ifieldRefCount);
3672                 j = 1;
3673             }
3674         } else if (j) {
3675             assert(false);
3676         }
3677     }
3678     if (!j) {
3679         assert(clazz->ifieldRefCount == clazz->ifieldCount);
3680     }
3681 #endif
3682 
3683     /*
3684      * We map a C struct directly on top of java/lang/Class objects.  Make
3685      * sure we left enough room for the instance fields.
3686      */
3687     assert(clazz != gDvm.classJavaLangClass || (size_t)fieldOffset <
3688         offsetof(ClassObject, instanceData) + sizeof(clazz->instanceData));
3689 
3690     clazz->objectSize = fieldOffset;
3691 
3692     dvmLinearReadOnly(clazz->classLoader, clazz->ifields);
3693     return true;
3694 }
3695 
3696 /*
3697  * Throw the VM-spec-mandated error when an exception is thrown during
3698  * class initialization.
3699  *
3700  * The safest way to do this is to call the ExceptionInInitializerError
3701  * constructor that takes a Throwable.
3702  *
3703  * [Do we want to wrap it if the original is an Error rather than
3704  * an Exception?]
3705  */
throwClinitError(void)3706 static void throwClinitError(void)
3707 {
3708     Thread* self = dvmThreadSelf();
3709     Object* exception;
3710     Object* eiie;
3711 
3712     exception = dvmGetException(self);
3713     dvmAddTrackedAlloc(exception, self);
3714     dvmClearException(self);
3715 
3716     if (gDvm.classJavaLangExceptionInInitializerError == NULL) {
3717         /*
3718          * Always resolves to same thing -- no race condition.
3719          */
3720         gDvm.classJavaLangExceptionInInitializerError =
3721             dvmFindSystemClass(
3722                     "Ljava/lang/ExceptionInInitializerError;");
3723         if (gDvm.classJavaLangExceptionInInitializerError == NULL) {
3724             LOGE("Unable to prep java/lang/ExceptionInInitializerError\n");
3725             goto fail;
3726         }
3727 
3728         gDvm.methJavaLangExceptionInInitializerError_init =
3729             dvmFindDirectMethodByDescriptor(gDvm.classJavaLangExceptionInInitializerError,
3730             "<init>", "(Ljava/lang/Throwable;)V");
3731         if (gDvm.methJavaLangExceptionInInitializerError_init == NULL) {
3732             LOGE("Unable to prep java/lang/ExceptionInInitializerError\n");
3733             goto fail;
3734         }
3735     }
3736 
3737     eiie = dvmAllocObject(gDvm.classJavaLangExceptionInInitializerError,
3738                 ALLOC_DEFAULT);
3739     if (eiie == NULL)
3740         goto fail;
3741 
3742     /*
3743      * Construct the new object, and replace the exception with it.
3744      */
3745     JValue unused;
3746     dvmCallMethod(self, gDvm.methJavaLangExceptionInInitializerError_init,
3747         eiie, &unused, exception);
3748     dvmSetException(self, eiie);
3749     dvmReleaseTrackedAlloc(eiie, NULL);
3750     dvmReleaseTrackedAlloc(exception, self);
3751     return;
3752 
3753 fail:       /* restore original exception */
3754     dvmSetException(self, exception);
3755     dvmReleaseTrackedAlloc(exception, self);
3756     return;
3757 }
3758 
3759 /*
3760  * The class failed to initialize on a previous attempt, so we want to throw
3761  * a NoClassDefFoundError (v2 2.17.5).  The exception to this rule is if we
3762  * failed in verification, in which case v2 5.4.1 says we need to re-throw
3763  * the previous error.
3764  */
throwEarlierClassFailure(ClassObject * clazz)3765 static void throwEarlierClassFailure(ClassObject* clazz)
3766 {
3767     LOGI("Rejecting re-init on previously-failed class %s v=%p\n",
3768         clazz->descriptor, clazz->verifyErrorClass);
3769 
3770     if (clazz->verifyErrorClass == NULL) {
3771         dvmThrowExceptionWithClassMessage("Ljava/lang/NoClassDefFoundError;",
3772             clazz->descriptor);
3773     } else {
3774         dvmThrowExceptionByClassWithClassMessage(clazz->verifyErrorClass,
3775             clazz->descriptor);
3776     }
3777 }
3778 
3779 /*
3780  * Initialize any static fields whose values are stored in
3781  * the DEX file.  This must be done during class initialization.
3782  */
initSFields(ClassObject * clazz)3783 static void initSFields(ClassObject* clazz)
3784 {
3785     Thread* self = dvmThreadSelf(); /* for dvmReleaseTrackedAlloc() */
3786     DexFile* pDexFile;
3787     const DexClassDef* pClassDef;
3788     const DexEncodedArray* pValueList;
3789     EncodedArrayIterator iterator;
3790     int i;
3791 
3792     if (clazz->sfieldCount == 0) {
3793         return;
3794     }
3795     if (clazz->pDvmDex == NULL) {
3796         /* generated class; any static fields should already be set up */
3797         LOGV("Not initializing static fields in %s\n", clazz->descriptor);
3798         return;
3799     }
3800     pDexFile = clazz->pDvmDex->pDexFile;
3801 
3802     pClassDef = dexFindClass(pDexFile, clazz->descriptor);
3803     assert(pClassDef != NULL);
3804 
3805     pValueList = dexGetStaticValuesList(pDexFile, pClassDef);
3806     if (pValueList == NULL) {
3807         return;
3808     }
3809 
3810     dvmEncodedArrayIteratorInitialize(&iterator, pValueList, clazz);
3811 
3812     /*
3813      * Iterate over the initial values array, setting the corresponding
3814      * static field for each array element.
3815      */
3816 
3817     for (i = 0; dvmEncodedArrayIteratorHasNext(&iterator); i++) {
3818         AnnotationValue value;
3819         bool parsed = dvmEncodedArrayIteratorGetNext(&iterator, &value);
3820         StaticField* sfield = &clazz->sfields[i];
3821         const char* descriptor = sfield->field.signature;
3822         bool needRelease = false;
3823 
3824         if (! parsed) {
3825             /*
3826              * TODO: Eventually verification should attempt to ensure
3827              * that this can't happen at least due to a data integrity
3828              * problem.
3829              */
3830             LOGE("Static initializer parse failed for %s at index %d",
3831                     clazz->descriptor, i);
3832             dvmAbort();
3833         }
3834 
3835         /* Verify that the value we got was of a valid type. */
3836 
3837         switch (descriptor[0]) {
3838             case 'Z': parsed = (value.type == kDexAnnotationBoolean); break;
3839             case 'B': parsed = (value.type == kDexAnnotationByte);    break;
3840             case 'C': parsed = (value.type == kDexAnnotationChar);    break;
3841             case 'S': parsed = (value.type == kDexAnnotationShort);   break;
3842             case 'I': parsed = (value.type == kDexAnnotationInt);     break;
3843             case 'J': parsed = (value.type == kDexAnnotationLong);    break;
3844             case 'F': parsed = (value.type == kDexAnnotationFloat);   break;
3845             case 'D': parsed = (value.type == kDexAnnotationDouble);  break;
3846             case '[': parsed = (value.type == kDexAnnotationNull);    break;
3847             case 'L': {
3848                 switch (value.type) {
3849                     case kDexAnnotationNull: {
3850                         /* No need for further tests. */
3851                         break;
3852                     }
3853                     case kDexAnnotationString: {
3854                         parsed =
3855                             (strcmp(descriptor, "Ljava/lang/String;") == 0);
3856                         needRelease = true;
3857                         break;
3858                     }
3859                     case kDexAnnotationType: {
3860                         parsed =
3861                             (strcmp(descriptor, "Ljava/lang/Class;") == 0);
3862                         needRelease = true;
3863                         break;
3864                     }
3865                     default: {
3866                         parsed = false;
3867                         break;
3868                     }
3869                 }
3870                 break;
3871             }
3872             default: {
3873                 parsed = false;
3874                 break;
3875             }
3876         }
3877 
3878         if (parsed) {
3879             /*
3880              * All's well, so store the value. Note: This always
3881              * stores the full width of a JValue, even though most of
3882              * the time only the first word is needed.
3883              */
3884             sfield->value = value.value;
3885             if (needRelease) {
3886                 dvmReleaseTrackedAlloc(value.value.l, self);
3887             }
3888         } else {
3889             /*
3890              * Something up above had a problem. TODO: See comment
3891              * above the switch about verfication.
3892              */
3893             LOGE("Bogus static initialization: value type %d in field type "
3894                     "%s for %s at index %d",
3895                 value.type, descriptor, clazz->descriptor, i);
3896             dvmAbort();
3897         }
3898     }
3899 }
3900 
3901 
3902 /*
3903  * Determine whether "descriptor" yields the same class object in the
3904  * context of clazz1 and clazz2.
3905  *
3906  * The caller must hold gDvm.loadedClasses.
3907  *
3908  * Returns "true" if they match.
3909  */
compareDescriptorClasses(const char * descriptor,const ClassObject * clazz1,const ClassObject * clazz2)3910 static bool compareDescriptorClasses(const char* descriptor,
3911     const ClassObject* clazz1, const ClassObject* clazz2)
3912 {
3913     ClassObject* result1;
3914     ClassObject* result2;
3915 
3916     /*
3917      * Do the first lookup by name.
3918      */
3919     result1 = dvmFindClassNoInit(descriptor, clazz1->classLoader);
3920 
3921     /*
3922      * We can skip a second lookup by name if the second class loader is
3923      * in the initiating loader list of the class object we retrieved.
3924      * (This means that somebody already did a lookup of this class through
3925      * the second loader, and it resolved to the same class.)  If it's not
3926      * there, we may simply not have had an opportunity to add it yet, so
3927      * we do the full lookup.
3928      *
3929      * The initiating loader test should catch the majority of cases
3930      * (in particular, the zillions of references to String/Object).
3931      *
3932      * Unfortunately we're still stuck grabbing a mutex to do the lookup.
3933      *
3934      * For this to work, the superclass/interface should be the first
3935      * argument, so that way if it's from the bootstrap loader this test
3936      * will work.  (The bootstrap loader, by definition, never shows up
3937      * as the initiating loader of a class defined by some other loader.)
3938      */
3939     dvmHashTableLock(gDvm.loadedClasses);
3940     bool isInit = dvmLoaderInInitiatingList(result1, clazz2->classLoader);
3941     dvmHashTableUnlock(gDvm.loadedClasses);
3942 
3943     if (isInit) {
3944         //printf("%s(obj=%p) / %s(cl=%p): initiating\n",
3945         //    result1->descriptor, result1,
3946         //    clazz2->descriptor, clazz2->classLoader);
3947         return true;
3948     } else {
3949         //printf("%s(obj=%p) / %s(cl=%p): RAW\n",
3950         //    result1->descriptor, result1,
3951         //    clazz2->descriptor, clazz2->classLoader);
3952         result2 = dvmFindClassNoInit(descriptor, clazz2->classLoader);
3953     }
3954 
3955     if (result1 == NULL || result2 == NULL) {
3956         dvmClearException(dvmThreadSelf());
3957         if (result1 == result2) {
3958             /*
3959              * Neither class loader could find this class.  Apparently it
3960              * doesn't exist.
3961              *
3962              * We can either throw some sort of exception now, or just
3963              * assume that it'll fail later when something actually tries
3964              * to use the class.  For strict handling we should throw now,
3965              * because a "tricky" class loader could start returning
3966              * something later, and a pair of "tricky" loaders could set
3967              * us up for confusion.
3968              *
3969              * I'm not sure if we're allowed to complain about nonexistent
3970              * classes in method signatures during class init, so for now
3971              * this will just return "true" and let nature take its course.
3972              */
3973             return true;
3974         } else {
3975             /* only one was found, so clearly they're not the same */
3976             return false;
3977         }
3978     }
3979 
3980     return result1 == result2;
3981 }
3982 
3983 /*
3984  * For every component in the method descriptor, resolve the class in the
3985  * context of the two classes and compare the results.
3986  *
3987  * For best results, the "superclass" class should be first.
3988  *
3989  * Returns "true" if the classes match, "false" otherwise.
3990  */
checkMethodDescriptorClasses(const Method * meth,const ClassObject * clazz1,const ClassObject * clazz2)3991 static bool checkMethodDescriptorClasses(const Method* meth,
3992     const ClassObject* clazz1, const ClassObject* clazz2)
3993 {
3994     DexParameterIterator iterator;
3995     const char* descriptor;
3996 
3997     /* walk through the list of parameters */
3998     dexParameterIteratorInit(&iterator, &meth->prototype);
3999     while (true) {
4000         descriptor = dexParameterIteratorNextDescriptor(&iterator);
4001 
4002         if (descriptor == NULL)
4003             break;
4004 
4005         if (descriptor[0] == 'L' || descriptor[0] == '[') {
4006             /* non-primitive type */
4007             if (!compareDescriptorClasses(descriptor, clazz1, clazz2))
4008                 return false;
4009         }
4010     }
4011 
4012     /* check the return type */
4013     descriptor = dexProtoGetReturnType(&meth->prototype);
4014     if (descriptor[0] == 'L' || descriptor[0] == '[') {
4015         if (!compareDescriptorClasses(descriptor, clazz1, clazz2))
4016             return false;
4017     }
4018     return true;
4019 }
4020 
4021 /*
4022  * Validate the descriptors in the superclass and interfaces.
4023  *
4024  * What we need to do is ensure that the classes named in the method
4025  * descriptors in our ancestors and ourselves resolve to the same class
4026  * objects.  We can get conflicts when the classes come from different
4027  * class loaders, and the resolver comes up with different results for
4028  * the same class name in different contexts.
4029  *
4030  * An easy way to cause the problem is to declare a base class that uses
4031  * class Foo in a method signature (e.g. as the return type).  Then,
4032  * define a subclass and a different version of Foo, and load them from a
4033  * different class loader.  If the subclass overrides the method, it will
4034  * have a different concept of what Foo is than its parent does, so even
4035  * though the method signature strings are identical, they actually mean
4036  * different things.
4037  *
4038  * A call to the method through a base-class reference would be treated
4039  * differently than a call to the method through a subclass reference, which
4040  * isn't the way polymorphism works, so we have to reject the subclass.
4041  * If the subclass doesn't override the base method, then there's no
4042  * problem, because calls through base-class references and subclass
4043  * references end up in the same place.
4044  *
4045  * We don't need to check to see if an interface's methods match with its
4046  * superinterface's methods, because you can't instantiate an interface
4047  * and do something inappropriate with it.  If interface I1 extends I2
4048  * and is implemented by C, and I1 and I2 are in separate class loaders
4049  * and have conflicting views of other classes, we will catch the conflict
4050  * when we process C.  Anything that implements I1 is doomed to failure,
4051  * but we don't need to catch that while processing I1.
4052  *
4053  * On failure, throws an exception and returns "false".
4054  */
validateSuperDescriptors(const ClassObject * clazz)4055 static bool validateSuperDescriptors(const ClassObject* clazz)
4056 {
4057     int i;
4058 
4059     if (dvmIsInterfaceClass(clazz))
4060         return true;
4061 
4062     /*
4063      * Start with the superclass-declared methods.
4064      */
4065     if (clazz->super != NULL &&
4066         clazz->classLoader != clazz->super->classLoader)
4067     {
4068         /*
4069          * Walk through every overridden method and compare resolved
4070          * descriptor components.  We pull the Method structs out of
4071          * the vtable.  It doesn't matter whether we get the struct from
4072          * the parent or child, since we just need the UTF-8 descriptor,
4073          * which must match.
4074          *
4075          * We need to do this even for the stuff inherited from Object,
4076          * because it's possible that the new class loader has redefined
4077          * a basic class like String.
4078          *
4079          * We don't need to check stuff defined in a superclass because
4080          * it was checked when the superclass was loaded.
4081          */
4082         const Method* meth;
4083 
4084         //printf("Checking %s %p vs %s %p\n",
4085         //    clazz->descriptor, clazz->classLoader,
4086         //    clazz->super->descriptor, clazz->super->classLoader);
4087         for (i = clazz->super->vtableCount - 1; i >= 0; i--) {
4088             meth = clazz->vtable[i];
4089             if (meth != clazz->super->vtable[i] &&
4090                 !checkMethodDescriptorClasses(meth, clazz->super, clazz))
4091             {
4092                 LOGW("Method mismatch: %s in %s (cl=%p) and super %s (cl=%p)\n",
4093                     meth->name, clazz->descriptor, clazz->classLoader,
4094                     clazz->super->descriptor, clazz->super->classLoader);
4095                 dvmThrowException("Ljava/lang/LinkageError;",
4096                     "Classes resolve differently in superclass");
4097                 return false;
4098             }
4099         }
4100     }
4101 
4102     /*
4103      * Check the methods defined by this class against the interfaces it
4104      * implements.  If we inherited the implementation from a superclass,
4105      * we have to check it against the superclass (which might be in a
4106      * different class loader).  If the superclass also implements the
4107      * interface, we could skip the check since by definition it was
4108      * performed when the class was loaded.
4109      */
4110     for (i = 0; i < clazz->iftableCount; i++) {
4111         const InterfaceEntry* iftable = &clazz->iftable[i];
4112 
4113         if (clazz->classLoader != iftable->clazz->classLoader) {
4114             const ClassObject* iface = iftable->clazz;
4115             int j;
4116 
4117             for (j = 0; j < iface->virtualMethodCount; j++) {
4118                 const Method* meth;
4119                 int vtableIndex;
4120 
4121                 vtableIndex = iftable->methodIndexArray[j];
4122                 meth = clazz->vtable[vtableIndex];
4123 
4124                 if (!checkMethodDescriptorClasses(meth, iface, meth->clazz)) {
4125                     LOGW("Method mismatch: %s in %s (cl=%p) and "
4126                             "iface %s (cl=%p)\n",
4127                         meth->name, clazz->descriptor, clazz->classLoader,
4128                         iface->descriptor, iface->classLoader);
4129                     dvmThrowException("Ljava/lang/LinkageError;",
4130                         "Classes resolve differently in interface");
4131                     return false;
4132                 }
4133             }
4134         }
4135     }
4136 
4137     return true;
4138 }
4139 
4140 /*
4141  * Returns true if the class is being initialized by us (which means that
4142  * calling dvmInitClass will return immediately after fiddling with locks).
4143  *
4144  * There isn't a race here, because either clazz->initThreadId won't match
4145  * us, or it will and it was set in the same thread.
4146  */
dvmIsClassInitializing(const ClassObject * clazz)4147 bool dvmIsClassInitializing(const ClassObject* clazz)
4148 {
4149     return (clazz->status == CLASS_INITIALIZING &&
4150             clazz->initThreadId == dvmThreadSelf()->threadId);
4151 }
4152 
4153 /*
4154  * If a class has not been initialized, do so by executing the code in
4155  * <clinit>.  The sequence is described in the VM spec v2 2.17.5.
4156  *
4157  * It is possible for multiple threads to arrive here simultaneously, so
4158  * we need to lock the class while we check stuff.  We know that no
4159  * interpreted code has access to the class yet, so we can use the class's
4160  * monitor lock.
4161  *
4162  * We will often be called recursively, e.g. when the <clinit> code resolves
4163  * one of its fields, the field resolution will try to initialize the class.
4164  *
4165  * This can get very interesting if a class has a static field initialized
4166  * to a new instance of itself.  <clinit> will end up calling <init> on
4167  * the members it is initializing, which is fine unless it uses the contents
4168  * of static fields to initialize instance fields.  This will leave the
4169  * static-referenced objects in a partially initialized state.  This is
4170  * reasonably rare and can sometimes be cured with proper field ordering.
4171  *
4172  * On failure, returns "false" with an exception raised.
4173  *
4174  * -----
4175  *
4176  * It is possible to cause a deadlock by having a situation like this:
4177  *   class A { static { sleep(10000); new B(); } }
4178  *   class B { static { sleep(10000); new A(); } }
4179  *   new Thread() { public void run() { new A(); } }.start();
4180  *   new Thread() { public void run() { new B(); } }.start();
4181  * This appears to be expected under the spec.
4182  *
4183  * The interesting question is what to do if somebody calls Thread.interrupt()
4184  * on one of the deadlocked threads.  According to the VM spec, they're both
4185  * sitting in "wait".  Should the interrupt code quietly raise the
4186  * "interrupted" flag, or should the "wait" return immediately with an
4187  * exception raised?
4188  *
4189  * This gets a little murky.  The VM spec says we call "wait", and the
4190  * spec for Thread.interrupt says Object.wait is interruptible.  So it
4191  * seems that, if we get unlucky and interrupt class initialization, we
4192  * are expected to throw (which gets converted to ExceptionInInitializerError
4193  * since InterruptedException is checked).
4194  *
4195  * There are a couple of problems here.  First, all threads are expected to
4196  * present a consistent view of class initialization, so we can't have it
4197  * fail in one thread and succeed in another.  Second, once a class fails
4198  * to initialize, it must *always* fail.  This means that a stray interrupt()
4199  * call could render a class unusable for the lifetime of the VM.
4200  *
4201  * In most cases -- the deadlock example above being a counter-example --
4202  * the interrupting thread can't tell whether the target thread handled
4203  * the initialization itself or had to wait while another thread did the
4204  * work.  Refusing to interrupt class initialization is, in most cases,
4205  * not something that a program can reliably detect.
4206  *
4207  * On the assumption that interrupting class initialization is highly
4208  * undesirable in most circumstances, and that failing to do so does not
4209  * deviate from the spec in a meaningful way, we don't allow class init
4210  * to be interrupted by Thread.interrupt().
4211  */
dvmInitClass(ClassObject * clazz)4212 bool dvmInitClass(ClassObject* clazz)
4213 {
4214 #if LOG_CLASS_LOADING
4215     bool initializedByUs = false;
4216 #endif
4217 
4218     Thread* self = dvmThreadSelf();
4219     const Method* method;
4220 
4221     dvmLockObject(self, (Object*) clazz);
4222     assert(dvmIsClassLinked(clazz) || clazz->status == CLASS_ERROR);
4223 
4224     /*
4225      * If the class hasn't been verified yet, do so now.
4226      */
4227     if (clazz->status < CLASS_VERIFIED) {
4228         /*
4229          * If we're in an "erroneous" state, throw an exception and bail.
4230          */
4231         if (clazz->status == CLASS_ERROR) {
4232             throwEarlierClassFailure(clazz);
4233             goto bail_unlock;
4234         }
4235 
4236         assert(clazz->status == CLASS_RESOLVED);
4237         assert(!IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED));
4238 
4239         if (gDvm.classVerifyMode == VERIFY_MODE_NONE ||
4240             (gDvm.classVerifyMode == VERIFY_MODE_REMOTE &&
4241              clazz->classLoader == NULL))
4242         {
4243             LOGV("+++ not verifying class %s (cl=%p)\n",
4244                 clazz->descriptor, clazz->classLoader);
4245             goto noverify;
4246         }
4247 
4248         if (!gDvm.optimizing)
4249             LOGV("+++ late verify on %s\n", clazz->descriptor);
4250 
4251         /*
4252          * We're not supposed to optimize an unverified class, but during
4253          * development this mode was useful.  We can't verify an optimized
4254          * class because the optimization process discards information.
4255          */
4256         if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOPTIMIZED)) {
4257             LOGW("Class '%s' was optimized without verification; "
4258                  "not verifying now\n",
4259                 clazz->descriptor);
4260             LOGW("  ('rm /data/dalvik-cache/*' and restart to fix this)");
4261             goto verify_failed;
4262         }
4263 
4264         clazz->status = CLASS_VERIFYING;
4265         if (!dvmVerifyClass(clazz, VERIFY_DEFAULT)) {
4266 verify_failed:
4267             dvmThrowExceptionWithClassMessage("Ljava/lang/VerifyError;",
4268                 clazz->descriptor);
4269             clazz->verifyErrorClass = dvmGetException(self)->clazz;
4270             clazz->status = CLASS_ERROR;
4271             goto bail_unlock;
4272         }
4273 
4274         clazz->status = CLASS_VERIFIED;
4275     }
4276 noverify:
4277 
4278     if (clazz->status == CLASS_INITIALIZED)
4279         goto bail_unlock;
4280 
4281     while (clazz->status == CLASS_INITIALIZING) {
4282         /* we caught somebody else in the act; was it us? */
4283         if (clazz->initThreadId == self->threadId) {
4284             //LOGV("HEY: found a recursive <clinit>\n");
4285             goto bail_unlock;
4286         }
4287 
4288         if (dvmCheckException(self)) {
4289             LOGW("GLITCH: exception pending at start of class init\n");
4290             dvmAbort();
4291         }
4292 
4293         /*
4294          * Wait for the other thread to finish initialization.  We pass
4295          * "false" for the "interruptShouldThrow" arg so it doesn't throw
4296          * an exception on interrupt.
4297          */
4298         dvmObjectWait(self, (Object*) clazz, 0, 0, false);
4299 
4300         /*
4301          * When we wake up, repeat the test for init-in-progress.  If there's
4302          * an exception pending (only possible if "interruptShouldThrow"
4303          * was set), bail out.
4304          */
4305         if (dvmCheckException(self)) {
4306             LOGI("Class init of '%s' failing with wait() exception\n",
4307                 clazz->descriptor);
4308             /*
4309              * TODO: this is bogus, because it means the two threads have a
4310              * different idea of the class status.  We need to flag the
4311              * class as bad and ensure that the initializer thread respects
4312              * our notice.  If we get lucky and wake up after the class has
4313              * finished initialization but before being woken, we have to
4314              * swallow the exception, perhaps raising thread->interrupted
4315              * to preserve semantics.
4316              *
4317              * Since we're not currently allowing interrupts, this should
4318              * never happen and we don't need to fix this.
4319              */
4320             assert(false);
4321             throwClinitError();
4322             clazz->status = CLASS_ERROR;
4323             goto bail_unlock;
4324         }
4325         if (clazz->status == CLASS_INITIALIZING) {
4326             LOGI("Waiting again for class init\n");
4327             continue;
4328         }
4329         assert(clazz->status == CLASS_INITIALIZED ||
4330                clazz->status == CLASS_ERROR);
4331         if (clazz->status == CLASS_ERROR) {
4332             /*
4333              * The caller wants an exception, but it was thrown in a
4334              * different thread.  Synthesize one here.
4335              */
4336             dvmThrowException("Ljava/lang/UnsatisfiedLinkError;",
4337                 "(<clinit> failed, see exception in other thread)");
4338         }
4339         goto bail_unlock;
4340     }
4341 
4342     /* see if we failed previously */
4343     if (clazz->status == CLASS_ERROR) {
4344         // might be wise to unlock before throwing; depends on which class
4345         // it is that we have locked
4346         dvmUnlockObject(self, (Object*) clazz);
4347         throwEarlierClassFailure(clazz);
4348         return false;
4349     }
4350 
4351     /*
4352      * We're ready to go, and have exclusive access to the class.
4353      *
4354      * Before we start initialization, we need to do one extra bit of
4355      * validation: make sure that the methods declared here match up
4356      * with our superclass and interfaces.  We know that the UTF-8
4357      * descriptors match, but classes from different class loaders can
4358      * have the same name.
4359      *
4360      * We do this now, rather than at load/link time, for the same reason
4361      * that we defer verification.
4362      *
4363      * It's unfortunate that we need to do this at all, but we risk
4364      * mixing reference types with identical names (see Dalvik test 068).
4365      */
4366     if (!validateSuperDescriptors(clazz)) {
4367         assert(dvmCheckException(self));
4368         clazz->status = CLASS_ERROR;
4369         goto bail_unlock;
4370     }
4371 
4372     /*
4373      * Let's initialize this thing.
4374      *
4375      * We unlock the object so that other threads can politely sleep on
4376      * our mutex with Object.wait(), instead of hanging or spinning trying
4377      * to grab our mutex.
4378      */
4379     assert(clazz->status < CLASS_INITIALIZING);
4380 
4381 #if LOG_CLASS_LOADING
4382     // We started initializing.
4383     logClassLoad('+', clazz);
4384     initializedByUs = true;
4385 #endif
4386 
4387     clazz->status = CLASS_INITIALIZING;
4388     clazz->initThreadId = self->threadId;
4389     dvmUnlockObject(self, (Object*) clazz);
4390 
4391     /* init our superclass */
4392     if (clazz->super != NULL && clazz->super->status != CLASS_INITIALIZED) {
4393         assert(!dvmIsInterfaceClass(clazz));
4394         if (!dvmInitClass(clazz->super)) {
4395             assert(dvmCheckException(self));
4396             clazz->status = CLASS_ERROR;
4397             /* wake up anybody who started waiting while we were unlocked */
4398             dvmLockObject(self, (Object*) clazz);
4399             goto bail_notify;
4400         }
4401     }
4402 
4403     /* Initialize any static fields whose values are
4404      * stored in the Dex file.  This should include all of the
4405      * simple "final static" fields, which are required to
4406      * be initialized first. (vmspec 2 sec 2.17.5 item 8)
4407      * More-complicated final static fields should be set
4408      * at the beginning of <clinit>;  all we can do is trust
4409      * that the compiler did the right thing.
4410      */
4411     initSFields(clazz);
4412 
4413     /* Execute any static initialization code.
4414      */
4415     method = dvmFindDirectMethodByDescriptor(clazz, "<clinit>", "()V");
4416     if (method == NULL) {
4417         LOGVV("No <clinit> found for %s\n", clazz->descriptor);
4418     } else {
4419         LOGVV("Invoking %s.<clinit>\n", clazz->descriptor);
4420         JValue unused;
4421         dvmCallMethod(self, method, NULL, &unused);
4422     }
4423 
4424     /* Set the bitmap of reference offsets. Except for class Object,
4425      * start with the superclass offsets.
4426      */
4427     if (clazz->super != NULL) {
4428         clazz->refOffsets = clazz->super->refOffsets;
4429     } else {
4430         clazz->refOffsets = 0;
4431     }
4432     /*
4433      * If our superclass overflowed, we don't stand a chance.
4434      */
4435     if (clazz->refOffsets != CLASS_WALK_SUPER) {
4436         InstField *f;
4437         int i;
4438 
4439         /* All of the fields that contain object references
4440          * are guaranteed to be at the beginning of the ifields list.
4441          */
4442         f = clazz->ifields;
4443         for (i = 0; i < clazz->ifieldRefCount; i++) {
4444             /*
4445              * Note that, per the comment on struct InstField,
4446              * f->byteOffset is the offset from the beginning of
4447              * obj, not the offset into obj->instanceData.
4448              */
4449             assert(f->byteOffset >= (int) CLASS_SMALLEST_OFFSET);
4450             assert((f->byteOffset & (CLASS_OFFSET_ALIGNMENT - 1)) == 0);
4451             u4 newBit = CLASS_BIT_FROM_OFFSET(f->byteOffset);
4452             if (newBit != 0) {
4453                 clazz->refOffsets |= newBit;
4454             } else {
4455                 clazz->refOffsets = CLASS_WALK_SUPER;
4456                 break;
4457             }
4458             f++;
4459         }
4460     }
4461 
4462     if (dvmCheckException(self)) {
4463         /*
4464          * We've had an exception thrown during static initialization.  We
4465          * need to throw an ExceptionInInitializerError, but we want to
4466          * tuck the original exception into the "cause" field.
4467          */
4468         LOGW("Exception %s thrown during %s.<clinit>\n",
4469             (dvmGetException(self)->clazz)->descriptor, clazz->descriptor);
4470         throwClinitError();
4471         //LOGW("+++ replaced\n");
4472 
4473         dvmLockObject(self, (Object*) clazz);
4474         clazz->status = CLASS_ERROR;
4475     } else {
4476         /* success! */
4477         dvmLockObject(self, (Object*) clazz);
4478         clazz->status = CLASS_INITIALIZED;
4479         LOGVV("Initialized class: %s\n", clazz->descriptor);
4480     }
4481 
4482 bail_notify:
4483     /*
4484      * Notify anybody waiting on the object.
4485      */
4486     dvmObjectNotifyAll(self, (Object*) clazz);
4487 
4488 bail_unlock:
4489 
4490 #if LOG_CLASS_LOADING
4491     if (initializedByUs) {
4492         // We finished initializing.
4493         logClassLoad('-', clazz);
4494     }
4495 #endif
4496 
4497     dvmUnlockObject(self, (Object*) clazz);
4498 
4499     return (clazz->status != CLASS_ERROR);
4500 }
4501 
4502 /*
4503  * Replace method->nativeFunc and method->insns with new values.  This is
4504  * performed on resolution of a native method.
4505  */
dvmSetNativeFunc(const Method * method,DalvikBridgeFunc func,const u2 * insns)4506 void dvmSetNativeFunc(const Method* method, DalvikBridgeFunc func,
4507     const u2* insns)
4508 {
4509     ClassObject* clazz = method->clazz;
4510 
4511     /* just open up both; easier that way */
4512     dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
4513     dvmLinearReadWrite(clazz->classLoader, clazz->directMethods);
4514 
4515     ((Method*)method)->nativeFunc = func;
4516     ((Method*)method)->insns = insns;
4517 
4518     dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
4519     dvmLinearReadOnly(clazz->classLoader, clazz->directMethods);
4520 }
4521 
4522 /*
4523  * Add a RegisterMap to a Method.  This is done when we verify the class
4524  * and compute the register maps at class initialization time (i.e. when
4525  * we don't have a pre-generated map).  This means "pMap" is on the heap
4526  * and should be freed when the Method is discarded.
4527  */
dvmSetRegisterMap(Method * method,const RegisterMap * pMap)4528 void dvmSetRegisterMap(Method* method, const RegisterMap* pMap)
4529 {
4530     ClassObject* clazz = method->clazz;
4531 
4532     if (method->registerMap != NULL) {
4533         /* unexpected during class loading, okay on first use (uncompress) */
4534         LOGV("NOTE: registerMap already set for %s.%s\n",
4535             method->clazz->descriptor, method->name);
4536         /* keep going */
4537     }
4538     assert(!dvmIsNativeMethod(method) && !dvmIsAbstractMethod(method));
4539 
4540     /* might be virtual or direct */
4541     dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
4542     dvmLinearReadWrite(clazz->classLoader, clazz->directMethods);
4543 
4544     method->registerMap = pMap;
4545 
4546     dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
4547     dvmLinearReadOnly(clazz->classLoader, clazz->directMethods);
4548 }
4549 
4550 /*
4551  * dvmHashForeach callback.  A nonzero return value causes foreach to
4552  * bail out.
4553  */
findClassCallback(void * vclazz,void * arg)4554 static int findClassCallback(void* vclazz, void* arg)
4555 {
4556     ClassObject* clazz = vclazz;
4557     const char* descriptor = (const char*) arg;
4558 
4559     if (strcmp(clazz->descriptor, descriptor) == 0)
4560         return (int) clazz;
4561     return 0;
4562 }
4563 
4564 /*
4565  * Find a loaded class by descriptor. Returns the first one found.
4566  * Because there can be more than one if class loaders are involved,
4567  * this is not an especially good API. (Currently only used by the
4568  * debugger and "checking" JNI.)
4569  *
4570  * "descriptor" should have the form "Ljava/lang/Class;" or
4571  * "[Ljava/lang/Class;", i.e. a descriptor and not an internal-form
4572  * class name.
4573  */
dvmFindLoadedClass(const char * descriptor)4574 ClassObject* dvmFindLoadedClass(const char* descriptor)
4575 {
4576     int result;
4577 
4578     dvmHashTableLock(gDvm.loadedClasses);
4579     result = dvmHashForeach(gDvm.loadedClasses, findClassCallback,
4580             (void*) descriptor);
4581     dvmHashTableUnlock(gDvm.loadedClasses);
4582 
4583     return (ClassObject*) result;
4584 }
4585 
4586 /*
4587  * Retrieve the system (a/k/a application) class loader.
4588  */
dvmGetSystemClassLoader(void)4589 Object* dvmGetSystemClassLoader(void)
4590 {
4591     ClassObject* clazz;
4592     Method* getSysMeth;
4593     Object* loader;
4594 
4595     clazz = dvmFindSystemClass("Ljava/lang/ClassLoader;");
4596     if (clazz == NULL)
4597         return NULL;
4598 
4599     getSysMeth = dvmFindDirectMethodByDescriptor(clazz, "getSystemClassLoader",
4600         "()Ljava/lang/ClassLoader;");
4601     if (getSysMeth == NULL)
4602         return NULL;
4603 
4604     JValue result;
4605     dvmCallMethod(dvmThreadSelf(), getSysMeth, NULL, &result);
4606     loader = (Object*)result.l;
4607     return loader;
4608 }
4609 
4610 
4611 /*
4612  * This is a dvmHashForeach callback.
4613  */
dumpClass(void * vclazz,void * varg)4614 static int dumpClass(void* vclazz, void* varg)
4615 {
4616     const ClassObject* clazz = (const ClassObject*) vclazz;
4617     const ClassObject* super;
4618     int flags = (int) varg;
4619     char* desc;
4620     int i;
4621 
4622     if (clazz == NULL) {
4623         LOGI("dumpClass: ignoring request to dump null class\n");
4624         return 0;
4625     }
4626 
4627     if ((flags & kDumpClassFullDetail) == 0) {
4628         bool showInit = (flags & kDumpClassInitialized) != 0;
4629         bool showLoader = (flags & kDumpClassClassLoader) != 0;
4630         const char* initStr;
4631 
4632         initStr = dvmIsClassInitialized(clazz) ? "true" : "false";
4633 
4634         if (showInit && showLoader)
4635             LOGI("%s %p %s\n", clazz->descriptor, clazz->classLoader, initStr);
4636         else if (showInit)
4637             LOGI("%s %s\n", clazz->descriptor, initStr);
4638         else if (showLoader)
4639             LOGI("%s %p\n", clazz->descriptor, clazz->classLoader);
4640         else
4641             LOGI("%s\n", clazz->descriptor);
4642 
4643         return 0;
4644     }
4645 
4646     /* clazz->super briefly holds the superclass index during class prep */
4647     if ((u4)clazz->super > 0x10000 && (u4) clazz->super != (u4)-1)
4648         super = clazz->super;
4649     else
4650         super = NULL;
4651 
4652     LOGI("----- %s '%s' cl=%p ser=0x%08x -----\n",
4653         dvmIsInterfaceClass(clazz) ? "interface" : "class",
4654         clazz->descriptor, clazz->classLoader, clazz->serialNumber);
4655     LOGI("  objectSize=%d (%d from super)\n", (int) clazz->objectSize,
4656         super != NULL ? (int) super->objectSize : -1);
4657     LOGI("  access=0x%04x.%04x\n", clazz->accessFlags >> 16,
4658         clazz->accessFlags & JAVA_FLAGS_MASK);
4659     if (super != NULL)
4660         LOGI("  super='%s' (cl=%p)\n", super->descriptor, super->classLoader);
4661     if (dvmIsArrayClass(clazz)) {
4662         LOGI("  dimensions=%d elementClass=%s\n",
4663             clazz->arrayDim, clazz->elementClass->descriptor);
4664     }
4665     if (clazz->iftableCount > 0) {
4666         LOGI("  interfaces (%d):\n", clazz->iftableCount);
4667         for (i = 0; i < clazz->iftableCount; i++) {
4668             InterfaceEntry* ent = &clazz->iftable[i];
4669             int j;
4670 
4671             LOGI("    %2d: %s (cl=%p)\n",
4672                 i, ent->clazz->descriptor, ent->clazz->classLoader);
4673 
4674             /* enable when needed */
4675             if (false && ent->methodIndexArray != NULL) {
4676                 for (j = 0; j < ent->clazz->virtualMethodCount; j++)
4677                     LOGI("      %2d: %d %s %s\n",
4678                         j, ent->methodIndexArray[j],
4679                         ent->clazz->virtualMethods[j].name,
4680                         clazz->vtable[ent->methodIndexArray[j]]->name);
4681             }
4682         }
4683     }
4684     if (!dvmIsInterfaceClass(clazz)) {
4685         LOGI("  vtable (%d entries, %d in super):\n", clazz->vtableCount,
4686             super != NULL ? super->vtableCount : 0);
4687         for (i = 0; i < clazz->vtableCount; i++) {
4688             desc = dexProtoCopyMethodDescriptor(&clazz->vtable[i]->prototype);
4689             LOGI("    %s%2d: %p %20s %s\n",
4690                 (i != clazz->vtable[i]->methodIndex) ? "*** " : "",
4691                 (u4) clazz->vtable[i]->methodIndex, clazz->vtable[i],
4692                 clazz->vtable[i]->name, desc);
4693             free(desc);
4694         }
4695         LOGI("  direct methods (%d entries):\n", clazz->directMethodCount);
4696         for (i = 0; i < clazz->directMethodCount; i++) {
4697             desc = dexProtoCopyMethodDescriptor(
4698                     &clazz->directMethods[i].prototype);
4699             LOGI("    %2d: %20s %s\n", i, clazz->directMethods[i].name,
4700                 desc);
4701             free(desc);
4702         }
4703     } else {
4704         LOGI("  interface methods (%d):\n", clazz->virtualMethodCount);
4705         for (i = 0; i < clazz->virtualMethodCount; i++) {
4706             desc = dexProtoCopyMethodDescriptor(
4707                     &clazz->virtualMethods[i].prototype);
4708             LOGI("    %2d: %2d %20s %s\n", i,
4709                 (u4) clazz->virtualMethods[i].methodIndex,
4710                 clazz->virtualMethods[i].name,
4711                 desc);
4712             free(desc);
4713         }
4714     }
4715     if (clazz->sfieldCount > 0) {
4716         LOGI("  static fields (%d entries):\n", clazz->sfieldCount);
4717         for (i = 0; i < clazz->sfieldCount; i++) {
4718             LOGI("    %2d: %20s %s\n", i, clazz->sfields[i].field.name,
4719                 clazz->sfields[i].field.signature);
4720         }
4721     }
4722     if (clazz->ifieldCount > 0) {
4723         LOGI("  instance fields (%d entries):\n", clazz->ifieldCount);
4724         for (i = 0; i < clazz->ifieldCount; i++) {
4725             LOGI("    %2d: %20s %s\n", i, clazz->ifields[i].field.name,
4726                 clazz->ifields[i].field.signature);
4727         }
4728     }
4729     return 0;
4730 }
4731 
4732 /*
4733  * Dump the contents of a single class.
4734  *
4735  * Pass kDumpClassFullDetail into "flags" to get lots of detail.
4736  */
dvmDumpClass(const ClassObject * clazz,int flags)4737 void dvmDumpClass(const ClassObject* clazz, int flags)
4738 {
4739     dumpClass((void*) clazz, (void*) flags);
4740 }
4741 
4742 /*
4743  * Dump the contents of all classes.
4744  */
dvmDumpAllClasses(int flags)4745 void dvmDumpAllClasses(int flags)
4746 {
4747     dvmHashTableLock(gDvm.loadedClasses);
4748     dvmHashForeach(gDvm.loadedClasses, dumpClass, (void*) flags);
4749     dvmHashTableUnlock(gDvm.loadedClasses);
4750 }
4751 
4752 /*
4753  * Get the number of loaded classes
4754  */
dvmGetNumLoadedClasses()4755 int dvmGetNumLoadedClasses()
4756 {
4757     int count;
4758     dvmHashTableLock(gDvm.loadedClasses);
4759     count = dvmHashTableNumEntries(gDvm.loadedClasses);
4760     dvmHashTableUnlock(gDvm.loadedClasses);
4761     return count;
4762 }
4763 
4764 /*
4765  * Write some statistics to the log file.
4766  */
dvmDumpLoaderStats(const char * msg)4767 void dvmDumpLoaderStats(const char* msg)
4768 {
4769     LOGV("VM stats (%s): cls=%d/%d meth=%d ifld=%d sfld=%d linear=%d\n",
4770         msg, gDvm.numLoadedClasses, dvmHashTableNumEntries(gDvm.loadedClasses),
4771         gDvm.numDeclaredMethods, gDvm.numDeclaredInstFields,
4772         gDvm.numDeclaredStaticFields, gDvm.pBootLoaderAlloc->curOffset);
4773 #ifdef COUNT_PRECISE_METHODS
4774     LOGI("GC precise methods: %d\n",
4775         dvmPointerSetGetCount(gDvm.preciseMethods));
4776 #endif
4777 }
4778 
4779 #ifdef PROFILE_FIELD_ACCESS
4780 /*
4781  * Dump the field access counts for all fields in this method.
4782  */
dumpAccessCounts(void * vclazz,void * varg)4783 static int dumpAccessCounts(void* vclazz, void* varg)
4784 {
4785     const ClassObject* clazz = (const ClassObject*) vclazz;
4786     int i;
4787 
4788     for (i = 0; i < clazz->ifieldCount; i++) {
4789         Field* field = &clazz->ifields[i].field;
4790 
4791         if (field->gets != 0)
4792             printf("GI %d %s.%s\n", field->gets,
4793                 field->clazz->descriptor, field->name);
4794         if (field->puts != 0)
4795             printf("PI %d %s.%s\n", field->puts,
4796                 field->clazz->descriptor, field->name);
4797     }
4798     for (i = 0; i < clazz->sfieldCount; i++) {
4799         Field* field = &clazz->sfields[i].field;
4800 
4801         if (field->gets != 0)
4802             printf("GS %d %s.%s\n", field->gets,
4803                 field->clazz->descriptor, field->name);
4804         if (field->puts != 0)
4805             printf("PS %d %s.%s\n", field->puts,
4806                 field->clazz->descriptor, field->name);
4807     }
4808 
4809     return 0;
4810 }
4811 
4812 /*
4813  * Dump the field access counts for all loaded classes.
4814  */
dvmDumpFieldAccessCounts(void)4815 void dvmDumpFieldAccessCounts(void)
4816 {
4817     dvmHashTableLock(gDvm.loadedClasses);
4818     dvmHashForeach(gDvm.loadedClasses, dumpAccessCounts, NULL);
4819     dvmHashTableUnlock(gDvm.loadedClasses);
4820 }
4821 #endif
4822 
4823 
4824 /*
4825  * Mark all classes associated with the built-in loader.
4826  */
markClassObject(void * clazz,void * arg)4827 static int markClassObject(void *clazz, void *arg)
4828 {
4829     UNUSED_PARAMETER(arg);
4830 
4831     dvmMarkObjectNonNull((Object *)clazz);
4832     return 0;
4833 }
4834 
4835 /*
4836  * The garbage collector calls this to mark the class objects for all
4837  * loaded classes.
4838  */
dvmGcScanRootClassLoader()4839 void dvmGcScanRootClassLoader()
4840 {
4841     /* dvmClassStartup() may not have been called before the first GC.
4842      */
4843     if (gDvm.loadedClasses != NULL) {
4844         dvmHashTableLock(gDvm.loadedClasses);
4845         dvmHashForeach(gDvm.loadedClasses, markClassObject, NULL);
4846         dvmHashTableUnlock(gDvm.loadedClasses);
4847     }
4848 }
4849 
4850 
4851 /*
4852  * ===========================================================================
4853  *      Method Prototypes and Descriptors
4854  * ===========================================================================
4855  */
4856 
4857 /*
4858  * Compare the two method names and prototypes, a la strcmp(). The
4859  * name is considered the "major" order and the prototype the "minor"
4860  * order. The prototypes are compared as if by dvmCompareMethodProtos().
4861  */
dvmCompareMethodNamesAndProtos(const Method * method1,const Method * method2)4862 int dvmCompareMethodNamesAndProtos(const Method* method1,
4863         const Method* method2)
4864 {
4865     int result = strcmp(method1->name, method2->name);
4866 
4867     if (result != 0) {
4868         return result;
4869     }
4870 
4871     return dvmCompareMethodProtos(method1, method2);
4872 }
4873 
4874 /*
4875  * Compare the two method names and prototypes, a la strcmp(), ignoring
4876  * the return value. The name is considered the "major" order and the
4877  * prototype the "minor" order. The prototypes are compared as if by
4878  * dvmCompareMethodArgProtos().
4879  */
dvmCompareMethodNamesAndParameterProtos(const Method * method1,const Method * method2)4880 int dvmCompareMethodNamesAndParameterProtos(const Method* method1,
4881         const Method* method2)
4882 {
4883     int result = strcmp(method1->name, method2->name);
4884 
4885     if (result != 0) {
4886         return result;
4887     }
4888 
4889     return dvmCompareMethodParameterProtos(method1, method2);
4890 }
4891 
4892 /*
4893  * Compare a (name, prototype) pair with the (name, prototype) of
4894  * a method, a la strcmp(). The name is considered the "major" order and
4895  * the prototype the "minor" order. The descriptor and prototype are
4896  * compared as if by dvmCompareDescriptorAndMethodProto().
4897  */
dvmCompareNameProtoAndMethod(const char * name,const DexProto * proto,const Method * method)4898 int dvmCompareNameProtoAndMethod(const char* name,
4899     const DexProto* proto, const Method* method)
4900 {
4901     int result = strcmp(name, method->name);
4902 
4903     if (result != 0) {
4904         return result;
4905     }
4906 
4907     return dexProtoCompare(proto, &method->prototype);
4908 }
4909 
4910 /*
4911  * Compare a (name, method descriptor) pair with the (name, prototype) of
4912  * a method, a la strcmp(). The name is considered the "major" order and
4913  * the prototype the "minor" order. The descriptor and prototype are
4914  * compared as if by dvmCompareDescriptorAndMethodProto().
4915  */
dvmCompareNameDescriptorAndMethod(const char * name,const char * descriptor,const Method * method)4916 int dvmCompareNameDescriptorAndMethod(const char* name,
4917     const char* descriptor, const Method* method)
4918 {
4919     int result = strcmp(name, method->name);
4920 
4921     if (result != 0) {
4922         return result;
4923     }
4924 
4925     return dvmCompareDescriptorAndMethodProto(descriptor, method);
4926 }
4927