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 #include "analysis/Optimize.h" 27 28 #include <stdlib.h> 29 #include <stddef.h> 30 #include <sys/stat.h> 31 32 #if LOG_CLASS_LOADING 33 #include <unistd.h> 34 #include <pthread.h> 35 #include <cutils/process_name.h> 36 #include <sys/types.h> 37 #endif 38 39 /* 40 Notes on Linking and Verification 41 42 The basic way to retrieve a class is to load it, make sure its superclass 43 and interfaces are available, prepare its fields, and return it. This gets 44 a little more complicated when multiple threads can be trying to retrieve 45 the class simultaneously, requiring that we use the class object's monitor 46 to keep things orderly. 47 48 The linking (preparing, resolving) of a class can cause us to recursively 49 load superclasses and interfaces. Barring circular references (e.g. two 50 classes that are superclasses of each other), this will complete without 51 the loader attempting to access the partially-linked class. 52 53 With verification, the situation is different. If we try to verify 54 every class as we load it, we quickly run into trouble. Even the lowly 55 java.lang.Object requires CloneNotSupportedException; follow the list 56 of referenced classes and you can head down quite a trail. The trail 57 eventually leads back to Object, which is officially not fully-formed yet. 58 59 The VM spec (specifically, v2 5.4.1) notes that classes pulled in during 60 verification do not need to be prepared or verified. This means that we 61 are allowed to have loaded but unverified classes. It further notes that 62 the class must be verified before it is initialized, which allows us to 63 defer verification for all classes until class init. You can't execute 64 code or access fields in an uninitialized class, so this is safe. 65 66 It also allows a more peaceful coexistence between verified and 67 unverifiable code. If class A refers to B, and B has a method that 68 refers to a bogus class C, should we allow class A to be verified? 69 If A only exercises parts of B that don't use class C, then there is 70 nothing wrong with running code in A. We can fully verify both A and B, 71 and allow execution to continue until B causes initialization of C. The 72 VerifyError is thrown close to the point of use. 73 74 This gets a little weird with java.lang.Class, which is the only class 75 that can be instantiated before it is initialized. We have to force 76 initialization right after the class is created, because by definition we 77 have instances of it on the heap, and somebody might get a class object and 78 start making virtual calls on it. We can end up going recursive during 79 verification of java.lang.Class, but we avoid that by checking to see if 80 verification is already in progress before we try to initialize it. 81 */ 82 83 /* 84 Notes on class loaders and interaction with optimization / verification 85 86 In what follows, "pre-verification" and "optimization" are the steps 87 performed by the dexopt command, which attempts to verify and optimize 88 classes as part of unpacking jar files and storing the DEX data in the 89 dalvik-cache directory. These steps are performed by loading the DEX 90 files directly, without any assistance from ClassLoader instances. 91 92 When we pre-verify and optimize a class in a DEX file, we make some 93 assumptions about where the class loader will go to look for classes. 94 If we can't guarantee those assumptions, e.g. because a class ("AppClass") 95 references something not defined in the bootstrap jars or the AppClass jar, 96 we can't pre-verify or optimize the class. 97 98 The VM doesn't define the behavior of user-defined class loaders. 99 For example, suppose application class AppClass, loaded by UserLoader, 100 has a method that creates a java.lang.String. The first time 101 AppClass.stringyMethod tries to do something with java.lang.String, it 102 asks UserLoader to find it. UserLoader is expected to defer to its parent 103 loader, but isn't required to. UserLoader might provide a replacement 104 for String. 105 106 We can run into trouble if we pre-verify AppClass with the assumption that 107 java.lang.String will come from core.jar, and don't verify this assumption 108 at runtime. There are two places that an alternate implementation of 109 java.lang.String can come from: the AppClass jar, or from some other jar 110 that UserLoader knows about. (Someday UserLoader will be able to generate 111 some bytecode and call DefineClass, but not yet.) 112 113 To handle the first situation, the pre-verifier will explicitly check for 114 conflicts between the class being optimized/verified and the bootstrap 115 classes. If an app jar contains a class that has the same package and 116 class name as a class in a bootstrap jar, the verification resolver refuses 117 to find either, which will block pre-verification and optimization on 118 classes that reference ambiguity. The VM will postpone verification of 119 the app class until first load. 120 121 For the second situation, we need to ensure that all references from a 122 pre-verified class are satisified by the class' jar or earlier bootstrap 123 jars. In concrete terms: when resolving a reference to NewClass, 124 which was caused by a reference in class AppClass, we check to see if 125 AppClass was pre-verified. If so, we require that NewClass comes out 126 of either the AppClass jar or one of the jars in the bootstrap path. 127 (We may not control the class loaders, but we do manage the DEX files. 128 We can verify that it's either (loader==null && dexFile==a_boot_dex) 129 or (loader==UserLoader && dexFile==AppClass.dexFile). Classes from 130 DefineClass can't be pre-verified, so this doesn't apply.) 131 132 This should ensure that you can't "fake out" the pre-verifier by creating 133 a user-defined class loader that replaces system classes. It should 134 also ensure that you can write such a loader and have it work in the 135 expected fashion; all you lose is some performance due to "just-in-time 136 verification" and the lack of DEX optimizations. 137 138 There is a "back door" of sorts in the class resolution check, due to 139 the fact that the "class ref" entries are shared between the bytecode 140 and meta-data references (e.g. annotations and exception handler lists). 141 The class references in annotations have no bearing on class verification, 142 so when a class does an annotation query that causes a class reference 143 index to be resolved, we don't want to fail just because the calling 144 class was pre-verified and the resolved class is in some random DEX file. 145 The successful resolution adds the class to the "resolved classes" table, 146 so when optimized bytecode references it we don't repeat the resolve-time 147 check. We can avoid this by not updating the "resolved classes" table 148 when the class reference doesn't come out of something that has been 149 checked by the verifier, but that has a nonzero performance impact. 150 Since the ultimate goal of this test is to catch an unusual situation 151 (user-defined class loaders redefining core classes), the added caution 152 may not be worth the performance hit. 153 */ 154 155 /* 156 * Class serial numbers start at this value. We use a nonzero initial 157 * value so they stand out in binary dumps (e.g. hprof output). 158 */ 159 #define INITIAL_CLASS_SERIAL_NUMBER 0x50000000 160 161 /* 162 * Constant used to size an auxillary class object data structure. 163 * For optimum memory use this should be equal to or slightly larger than 164 * the number of classes loaded when the zygote finishes initializing. 165 */ 166 #define ZYGOTE_CLASS_CUTOFF 2304 167 168 #define CLASS_SFIELD_SLOTS 1 169 170 static ClassPathEntry* processClassPath(const char* pathStr, bool isBootstrap); 171 static void freeCpeArray(ClassPathEntry* cpe); 172 173 static ClassObject* findClassFromLoaderNoInit( 174 const char* descriptor, Object* loader); 175 static ClassObject* findClassNoInit(const char* descriptor, Object* loader,\ 176 DvmDex* pDvmDex); 177 static ClassObject* loadClassFromDex(DvmDex* pDvmDex, 178 const DexClassDef* pClassDef, Object* loader); 179 static void loadMethodFromDex(ClassObject* clazz, const DexMethod* pDexMethod,\ 180 Method* meth); 181 static int computeJniArgInfo(const DexProto* proto); 182 static void loadSFieldFromDex(ClassObject* clazz, 183 const DexField* pDexSField, StaticField* sfield); 184 static void loadIFieldFromDex(ClassObject* clazz, 185 const DexField* pDexIField, InstField* field); 186 static bool precacheReferenceOffsets(ClassObject* clazz); 187 static void computeRefOffsets(ClassObject* clazz); 188 static void freeMethodInnards(Method* meth); 189 static bool createVtable(ClassObject* clazz); 190 static bool createIftable(ClassObject* clazz); 191 static bool insertMethodStubs(ClassObject* clazz); 192 static bool computeFieldOffsets(ClassObject* clazz); 193 static void throwEarlierClassFailure(ClassObject* clazz); 194 195 #if LOG_CLASS_LOADING 196 /* 197 * Logs information about a class loading with given timestamp. 198 * 199 * TODO: In the case where we fail in dvmLinkClass() and log the class as closing (type='<'), 200 * it would probably be better to use a new type code to indicate the failure. This change would 201 * require a matching change in the parser and analysis code in frameworks/base/tools/preload. 202 */ 203 static void logClassLoadWithTime(char type, ClassObject* clazz, u8 time) { 204 pid_t ppid = getppid(); 205 pid_t pid = getpid(); 206 unsigned int tid = (unsigned int) pthread_self(); 207 208 ALOG(LOG_INFO, "PRELOAD", "%c%d:%d:%d:%s:%d:%s:%lld", type, ppid, pid, tid, 209 get_process_name(), (int) clazz->classLoader, clazz->descriptor, 210 time); 211 } 212 213 /* 214 * Logs information about a class loading. 215 */ 216 static void logClassLoad(char type, ClassObject* clazz) { 217 logClassLoadWithTime(type, clazz, dvmGetThreadCpuTimeNsec()); 218 } 219 #endif 220 221 /* 222 * Some LinearAlloc unit tests. 223 */ 224 static void linearAllocTests() 225 { 226 char* fiddle; 227 int test = 1; 228 229 switch (test) { 230 case 0: 231 fiddle = (char*)dvmLinearAlloc(NULL, 3200-28); 232 dvmLinearReadOnly(NULL, (char*)fiddle); 233 break; 234 case 1: 235 fiddle = (char*)dvmLinearAlloc(NULL, 3200-24); 236 dvmLinearReadOnly(NULL, (char*)fiddle); 237 break; 238 case 2: 239 fiddle = (char*)dvmLinearAlloc(NULL, 3200-20); 240 dvmLinearReadOnly(NULL, (char*)fiddle); 241 break; 242 case 3: 243 fiddle = (char*)dvmLinearAlloc(NULL, 3200-16); 244 dvmLinearReadOnly(NULL, (char*)fiddle); 245 break; 246 case 4: 247 fiddle = (char*)dvmLinearAlloc(NULL, 3200-12); 248 dvmLinearReadOnly(NULL, (char*)fiddle); 249 break; 250 } 251 fiddle = (char*)dvmLinearAlloc(NULL, 896); 252 dvmLinearReadOnly(NULL, (char*)fiddle); 253 fiddle = (char*)dvmLinearAlloc(NULL, 20); // watch addr of this alloc 254 dvmLinearReadOnly(NULL, (char*)fiddle); 255 256 fiddle = (char*)dvmLinearAlloc(NULL, 1); 257 fiddle[0] = 'q'; 258 dvmLinearReadOnly(NULL, fiddle); 259 fiddle = (char*)dvmLinearAlloc(NULL, 4096); 260 fiddle[0] = 'x'; 261 fiddle[4095] = 'y'; 262 dvmLinearReadOnly(NULL, fiddle); 263 dvmLinearFree(NULL, fiddle); 264 fiddle = (char*)dvmLinearAlloc(NULL, 0); 265 dvmLinearReadOnly(NULL, fiddle); 266 fiddle = (char*)dvmLinearRealloc(NULL, fiddle, 12); 267 fiddle[11] = 'z'; 268 dvmLinearReadOnly(NULL, (char*)fiddle); 269 fiddle = (char*)dvmLinearRealloc(NULL, fiddle, 5); 270 dvmLinearReadOnly(NULL, fiddle); 271 fiddle = (char*)dvmLinearAlloc(NULL, 17001); 272 fiddle[0] = 'x'; 273 fiddle[17000] = 'y'; 274 dvmLinearReadOnly(NULL, (char*)fiddle); 275 276 char* str = (char*)dvmLinearStrdup(NULL, "This is a test!"); 277 ALOGI("GOT: '%s'", str); 278 279 /* try to check the bounds; allocator may round allocation size up */ 280 fiddle = (char*)dvmLinearAlloc(NULL, 12); 281 ALOGI("Should be 1: %d", dvmLinearAllocContains(fiddle, 12)); 282 ALOGI("Should be 0: %d", dvmLinearAllocContains(fiddle, 13)); 283 ALOGI("Should be 0: %d", dvmLinearAllocContains(fiddle - 128*1024, 1)); 284 285 dvmLinearAllocDump(NULL); 286 dvmLinearFree(NULL, (char*)str); 287 } 288 289 static size_t classObjectSize(size_t sfieldCount) 290 { 291 size_t offset = OFFSETOF_MEMBER(ClassObject, sfields); 292 return offset + sizeof(StaticField) * sfieldCount; 293 } 294 295 size_t dvmClassObjectSize(const ClassObject *clazz) 296 { 297 assert(clazz != NULL); 298 return classObjectSize(clazz->sfieldCount); 299 } 300 301 /* (documented in header) */ 302 ClassObject* dvmFindPrimitiveClass(char type) 303 { 304 PrimitiveType primitiveType = dexGetPrimitiveTypeFromDescriptorChar(type); 305 306 switch (primitiveType) { 307 case PRIM_VOID: return gDvm.typeVoid; 308 case PRIM_BOOLEAN: return gDvm.typeBoolean; 309 case PRIM_BYTE: return gDvm.typeByte; 310 case PRIM_SHORT: return gDvm.typeShort; 311 case PRIM_CHAR: return gDvm.typeChar; 312 case PRIM_INT: return gDvm.typeInt; 313 case PRIM_LONG: return gDvm.typeLong; 314 case PRIM_FLOAT: return gDvm.typeFloat; 315 case PRIM_DOUBLE: return gDvm.typeDouble; 316 default: { 317 ALOGW("Unknown primitive type '%c'", type); 318 return NULL; 319 } 320 } 321 } 322 323 /* 324 * Synthesize a primitive class. 325 * 326 * Just creates the class and returns it (does not add it to the class list). 327 */ 328 static bool createPrimitiveType(PrimitiveType primitiveType, ClassObject** pClass) 329 { 330 /* 331 * Fill out a few fields in the ClassObject. 332 * 333 * Note that primitive classes do not sub-class the class Object. 334 * This matters for "instanceof" checks. Also, we assume that the 335 * primitive class does not override finalize(). 336 */ 337 338 const char* descriptor = dexGetPrimitiveTypeDescriptor(primitiveType); 339 assert(descriptor != NULL); 340 341 ClassObject* newClass = (ClassObject*) dvmMalloc(sizeof(*newClass), ALLOC_NON_MOVING); 342 if (newClass == NULL) { 343 return false; 344 } 345 346 DVM_OBJECT_INIT(newClass, gDvm.classJavaLangClass); 347 dvmSetClassSerialNumber(newClass); 348 SET_CLASS_FLAG(newClass, ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT); 349 newClass->primitiveType = primitiveType; 350 newClass->descriptorAlloc = NULL; 351 newClass->descriptor = descriptor; 352 newClass->super = NULL; 353 newClass->status = CLASS_INITIALIZED; 354 355 /* don't need to set newClass->objectSize */ 356 357 LOGVV("Constructed class for primitive type '%s'", newClass->descriptor); 358 359 *pClass = newClass; 360 dvmReleaseTrackedAlloc((Object*) newClass, NULL); 361 362 return true; 363 } 364 365 /* 366 * Create the initial class instances. These consist of the class 367 * Class and all of the classes representing primitive types. 368 */ 369 static bool createInitialClasses() { 370 /* 371 * Initialize the class Class. This has to be done specially, particularly 372 * because it is an instance of itself. 373 */ 374 ClassObject* clazz = (ClassObject*) 375 dvmMalloc(classObjectSize(CLASS_SFIELD_SLOTS), ALLOC_NON_MOVING); 376 if (clazz == NULL) { 377 return false; 378 } 379 DVM_OBJECT_INIT(clazz, clazz); 380 SET_CLASS_FLAG(clazz, ACC_PUBLIC | ACC_FINAL | CLASS_ISCLASS); 381 clazz->descriptor = "Ljava/lang/Class;"; 382 gDvm.classJavaLangClass = clazz; 383 LOGVV("Constructed the class Class."); 384 385 /* 386 * Initialize the classes representing primitive types. These are 387 * instances of the class Class, but other than that they're fairly 388 * different from regular classes. 389 */ 390 bool ok = true; 391 ok &= createPrimitiveType(PRIM_VOID, &gDvm.typeVoid); 392 ok &= createPrimitiveType(PRIM_BOOLEAN, &gDvm.typeBoolean); 393 ok &= createPrimitiveType(PRIM_BYTE, &gDvm.typeByte); 394 ok &= createPrimitiveType(PRIM_SHORT, &gDvm.typeShort); 395 ok &= createPrimitiveType(PRIM_CHAR, &gDvm.typeChar); 396 ok &= createPrimitiveType(PRIM_INT, &gDvm.typeInt); 397 ok &= createPrimitiveType(PRIM_LONG, &gDvm.typeLong); 398 ok &= createPrimitiveType(PRIM_FLOAT, &gDvm.typeFloat); 399 ok &= createPrimitiveType(PRIM_DOUBLE, &gDvm.typeDouble); 400 401 return ok; 402 } 403 404 /* 405 * Initialize the bootstrap class loader. 406 * 407 * Call this after the bootclasspath string has been finalized. 408 */ 409 bool dvmClassStartup() 410 { 411 /* make this a requirement -- don't currently support dirs in path */ 412 if (strcmp(gDvm.bootClassPathStr, ".") == 0) { 413 ALOGE("ERROR: must specify non-'.' bootclasspath"); 414 return false; 415 } 416 417 gDvm.loadedClasses = 418 dvmHashTableCreate(256, (HashFreeFunc) dvmFreeClassInnards); 419 420 gDvm.pBootLoaderAlloc = dvmLinearAllocCreate(NULL); 421 if (gDvm.pBootLoaderAlloc == NULL) 422 return false; 423 424 if (false) { 425 linearAllocTests(); 426 exit(0); 427 } 428 429 /* 430 * Class serial number. We start with a high value to make it distinct 431 * in binary dumps (e.g. hprof). 432 */ 433 gDvm.classSerialNumber = INITIAL_CLASS_SERIAL_NUMBER; 434 435 /* 436 * Set up the table we'll use for tracking initiating loaders for 437 * early classes. 438 * If it's NULL, we just fall back to the InitiatingLoaderList in the 439 * ClassObject, so it's not fatal to fail this allocation. 440 */ 441 gDvm.initiatingLoaderList = (InitiatingLoaderList*) 442 calloc(ZYGOTE_CLASS_CUTOFF, sizeof(InitiatingLoaderList)); 443 444 /* 445 * Create the initial classes. These are the first objects constructed 446 * within the nascent VM. 447 */ 448 if (!createInitialClasses()) { 449 return false; 450 } 451 452 /* 453 * Process the bootstrap class path. This means opening the specified 454 * DEX or Jar files and possibly running them through the optimizer. 455 */ 456 assert(gDvm.bootClassPath == NULL); 457 processClassPath(gDvm.bootClassPathStr, true); 458 459 if (gDvm.bootClassPath == NULL) 460 return false; 461 462 return true; 463 } 464 465 /* 466 * Clean up. 467 */ 468 void dvmClassShutdown() 469 { 470 /* discard all system-loaded classes */ 471 dvmHashTableFree(gDvm.loadedClasses); 472 gDvm.loadedClasses = NULL; 473 474 /* discard primitive classes created for arrays */ 475 dvmFreeClassInnards(gDvm.typeVoid); 476 dvmFreeClassInnards(gDvm.typeBoolean); 477 dvmFreeClassInnards(gDvm.typeByte); 478 dvmFreeClassInnards(gDvm.typeShort); 479 dvmFreeClassInnards(gDvm.typeChar); 480 dvmFreeClassInnards(gDvm.typeInt); 481 dvmFreeClassInnards(gDvm.typeLong); 482 dvmFreeClassInnards(gDvm.typeFloat); 483 dvmFreeClassInnards(gDvm.typeDouble); 484 485 /* this closes DEX files, JAR files, etc. */ 486 freeCpeArray(gDvm.bootClassPath); 487 gDvm.bootClassPath = NULL; 488 489 dvmLinearAllocDestroy(NULL); 490 491 free(gDvm.initiatingLoaderList); 492 } 493 494 495 /* 496 * =========================================================================== 497 * Bootstrap class loader 498 * =========================================================================== 499 */ 500 501 /* 502 * Dump the contents of a ClassPathEntry array. 503 */ 504 static void dumpClassPath(const ClassPathEntry* cpe) 505 { 506 int idx = 0; 507 508 while (cpe->kind != kCpeLastEntry) { 509 const char* kindStr; 510 511 switch (cpe->kind) { 512 case kCpeJar: kindStr = "jar"; break; 513 case kCpeDex: kindStr = "dex"; break; 514 default: kindStr = "???"; break; 515 } 516 517 ALOGI(" %2d: type=%s %s %p", idx, kindStr, cpe->fileName, cpe->ptr); 518 if (CALC_CACHE_STATS && cpe->kind == kCpeJar) { 519 JarFile* pJarFile = (JarFile*) cpe->ptr; 520 DvmDex* pDvmDex = dvmGetJarFileDex(pJarFile); 521 dvmDumpAtomicCacheStats(pDvmDex->pInterfaceCache); 522 } 523 524 cpe++; 525 idx++; 526 } 527 } 528 529 /* 530 * Dump the contents of the bootstrap class path. 531 */ 532 void dvmDumpBootClassPath() 533 { 534 dumpClassPath(gDvm.bootClassPath); 535 } 536 537 /* 538 * Returns "true" if the class path contains the specified path. 539 */ 540 bool dvmClassPathContains(const ClassPathEntry* cpe, const char* path) 541 { 542 while (cpe->kind != kCpeLastEntry) { 543 if (strcmp(cpe->fileName, path) == 0) 544 return true; 545 546 cpe++; 547 } 548 return false; 549 } 550 551 /* 552 * Free an array of ClassPathEntry structs. 553 * 554 * We release the contents of each entry, then free the array itself. 555 */ 556 static void freeCpeArray(ClassPathEntry* cpe) 557 { 558 ClassPathEntry* cpeStart = cpe; 559 560 if (cpe == NULL) 561 return; 562 563 while (cpe->kind != kCpeLastEntry) { 564 switch (cpe->kind) { 565 case kCpeJar: 566 /* free JarFile */ 567 dvmJarFileFree((JarFile*) cpe->ptr); 568 break; 569 case kCpeDex: 570 /* free RawDexFile */ 571 dvmRawDexFileFree((RawDexFile*) cpe->ptr); 572 break; 573 default: 574 assert(false); 575 break; 576 } 577 578 free(cpe->fileName); 579 cpe++; 580 } 581 582 free(cpeStart); 583 } 584 585 /* 586 * Get the filename suffix of the given file (everything after the 587 * last "." if any, or "<none>" if there's no apparent suffix). The 588 * passed-in buffer will always be '\0' terminated. 589 */ 590 static void getFileNameSuffix(const char* fileName, char* suffixBuf, size_t suffixBufLen) 591 { 592 const char* lastDot = strrchr(fileName, '.'); 593 594 strlcpy(suffixBuf, (lastDot == NULL) ? "<none>" : (lastDot + 1), suffixBufLen); 595 } 596 597 /* 598 * Prepare a ClassPathEntry struct, which at this point only has a valid 599 * filename. We need to figure out what kind of file it is, and for 600 * everything other than directories we need to open it up and see 601 * what's inside. 602 */ 603 static bool prepareCpe(ClassPathEntry* cpe, bool isBootstrap) 604 { 605 struct stat sb; 606 607 if (stat(cpe->fileName, &sb) < 0) { 608 ALOGD("Unable to stat classpath element '%s'", cpe->fileName); 609 return false; 610 } 611 if (S_ISDIR(sb.st_mode)) { 612 ALOGE("Directory classpath elements are not supported: %s", cpe->fileName); 613 return false; 614 } 615 616 char suffix[10]; 617 getFileNameSuffix(cpe->fileName, suffix, sizeof(suffix)); 618 619 if ((strcmp(suffix, "jar") == 0) || (strcmp(suffix, "zip") == 0) || 620 (strcmp(suffix, "apk") == 0)) { 621 JarFile* pJarFile = NULL; 622 if (dvmJarFileOpen(cpe->fileName, NULL, &pJarFile, isBootstrap) == 0) { 623 cpe->kind = kCpeJar; 624 cpe->ptr = pJarFile; 625 return true; 626 } 627 } else if (strcmp(suffix, "dex") == 0) { 628 RawDexFile* pRawDexFile = NULL; 629 if (dvmRawDexFileOpen(cpe->fileName, NULL, &pRawDexFile, isBootstrap) == 0) { 630 cpe->kind = kCpeDex; 631 cpe->ptr = pRawDexFile; 632 return true; 633 } 634 } else { 635 ALOGE("Unknown type suffix '%s'", suffix); 636 } 637 638 ALOGD("Unable to process classpath element '%s'", cpe->fileName); 639 return false; 640 } 641 642 /* 643 * Convert a colon-separated list of directories, Zip files, and DEX files 644 * into an array of ClassPathEntry structs. 645 * 646 * During normal startup we fail if there are no entries, because we won't 647 * get very far without the basic language support classes, but if we're 648 * optimizing a DEX file we allow it. 649 * 650 * If entries are added or removed from the bootstrap class path, the 651 * dependencies in the DEX files will break, and everything except the 652 * very first entry will need to be regenerated. 653 */ 654 static ClassPathEntry* processClassPath(const char* pathStr, bool isBootstrap) 655 { 656 ClassPathEntry* cpe = NULL; 657 char* mangle; 658 char* cp; 659 const char* end; 660 int idx, count; 661 662 assert(pathStr != NULL); 663 664 mangle = strdup(pathStr); 665 666 /* 667 * Run through and essentially strtok() the string. Get a count of 668 * the #of elements while we're at it. 669 * 670 * If the path was constructed strangely (e.g. ":foo::bar:") this will 671 * over-allocate, which isn't ideal but is mostly harmless. 672 */ 673 count = 1; 674 for (cp = mangle; *cp != '\0'; cp++) { 675 if (*cp == ':') { /* separates two entries */ 676 count++; 677 *cp = '\0'; 678 } 679 } 680 end = cp; 681 682 /* 683 * Allocate storage. We over-alloc by one so we can set an "end" marker. 684 */ 685 cpe = (ClassPathEntry*) calloc(count+1, sizeof(ClassPathEntry)); 686 687 /* 688 * Set the global pointer so the DEX file dependency stuff can find it. 689 */ 690 gDvm.bootClassPath = cpe; 691 692 /* 693 * Go through a second time, pulling stuff out. 694 */ 695 cp = mangle; 696 idx = 0; 697 while (cp < end) { 698 if (*cp == '\0') { 699 /* leading, trailing, or doubled ':'; ignore it */ 700 } else { 701 if (isBootstrap && 702 dvmPathToAbsolutePortion(cp) == NULL) { 703 ALOGE("Non-absolute bootclasspath entry '%s'", cp); 704 free(cpe); 705 cpe = NULL; 706 goto bail; 707 } 708 709 ClassPathEntry tmp; 710 tmp.kind = kCpeUnknown; 711 tmp.fileName = strdup(cp); 712 tmp.ptr = NULL; 713 714 /* 715 * Drop an end marker here so DEX loader can walk unfinished 716 * list. 717 */ 718 cpe[idx].kind = kCpeLastEntry; 719 cpe[idx].fileName = NULL; 720 cpe[idx].ptr = NULL; 721 722 if (!prepareCpe(&tmp, isBootstrap)) { 723 /* drop from list and continue on */ 724 free(tmp.fileName); 725 } else { 726 /* copy over, pointers and all */ 727 cpe[idx] = tmp; 728 idx++; 729 } 730 } 731 732 cp += strlen(cp) +1; 733 } 734 assert(idx <= count); 735 if (idx == 0 && !gDvm.optimizing) { 736 /* 737 * There's no way the vm will be doing anything if this is the 738 * case, so just bail out (reasonably) gracefully. 739 */ 740 ALOGE("No valid entries found in bootclasspath '%s'", pathStr); 741 gDvm.lastMessage = pathStr; 742 dvmAbort(); 743 } 744 745 LOGVV(" (filled %d of %d slots)", idx, count); 746 747 /* put end marker in over-alloc slot */ 748 cpe[idx].kind = kCpeLastEntry; 749 cpe[idx].fileName = NULL; 750 cpe[idx].ptr = NULL; 751 752 //dumpClassPath(cpe); 753 754 bail: 755 free(mangle); 756 gDvm.bootClassPath = cpe; 757 return cpe; 758 } 759 760 /* 761 * Search the DEX files we loaded from the bootstrap class path for a DEX 762 * file that has the class with the matching descriptor. 763 * 764 * Returns the matching DEX file and DexClassDef entry if found, otherwise 765 * returns NULL. 766 */ 767 static DvmDex* searchBootPathForClass(const char* descriptor, 768 const DexClassDef** ppClassDef) 769 { 770 const ClassPathEntry* cpe = gDvm.bootClassPath; 771 const DexClassDef* pFoundDef = NULL; 772 DvmDex* pFoundFile = NULL; 773 774 LOGVV("+++ class '%s' not yet loaded, scanning bootclasspath...", 775 descriptor); 776 777 while (cpe->kind != kCpeLastEntry) { 778 //ALOGV("+++ checking '%s' (%d)", cpe->fileName, cpe->kind); 779 780 switch (cpe->kind) { 781 case kCpeJar: 782 { 783 JarFile* pJarFile = (JarFile*) cpe->ptr; 784 const DexClassDef* pClassDef; 785 DvmDex* pDvmDex; 786 787 pDvmDex = dvmGetJarFileDex(pJarFile); 788 pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor); 789 if (pClassDef != NULL) { 790 /* found */ 791 pFoundDef = pClassDef; 792 pFoundFile = pDvmDex; 793 goto found; 794 } 795 } 796 break; 797 case kCpeDex: 798 { 799 RawDexFile* pRawDexFile = (RawDexFile*) cpe->ptr; 800 const DexClassDef* pClassDef; 801 DvmDex* pDvmDex; 802 803 pDvmDex = dvmGetRawDexFileDex(pRawDexFile); 804 pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor); 805 if (pClassDef != NULL) { 806 /* found */ 807 pFoundDef = pClassDef; 808 pFoundFile = pDvmDex; 809 goto found; 810 } 811 } 812 break; 813 default: 814 ALOGE("Unknown kind %d", cpe->kind); 815 assert(false); 816 break; 817 } 818 819 cpe++; 820 } 821 822 /* 823 * Special handling during verification + optimization. 824 * 825 * The DEX optimizer needs to load classes from the DEX file it's working 826 * on. Rather than trying to insert it into the bootstrap class path 827 * or synthesizing a class loader to manage it, we just make it available 828 * here. It logically comes after all existing entries in the bootstrap 829 * class path. 830 */ 831 if (gDvm.bootClassPathOptExtra != NULL) { 832 const DexClassDef* pClassDef; 833 834 pClassDef = 835 dexFindClass(gDvm.bootClassPathOptExtra->pDexFile, descriptor); 836 if (pClassDef != NULL) { 837 /* found */ 838 pFoundDef = pClassDef; 839 pFoundFile = gDvm.bootClassPathOptExtra; 840 } 841 } 842 843 found: 844 *ppClassDef = pFoundDef; 845 return pFoundFile; 846 } 847 848 /* 849 * Set the "extra" DEX, which becomes a de facto member of the bootstrap 850 * class set. 851 */ 852 void dvmSetBootPathExtraDex(DvmDex* pDvmDex) 853 { 854 gDvm.bootClassPathOptExtra = pDvmDex; 855 } 856 857 858 /* 859 * Return the #of entries in the bootstrap class path. 860 * 861 * (Used for ClassLoader.getResources().) 862 */ 863 int dvmGetBootPathSize() 864 { 865 const ClassPathEntry* cpe = gDvm.bootClassPath; 866 867 while (cpe->kind != kCpeLastEntry) 868 cpe++; 869 870 return cpe - gDvm.bootClassPath; 871 } 872 873 /* 874 * Find a resource with the specified name in entry N of the boot class path. 875 * 876 * We return a newly-allocated String of one of these forms: 877 * file://path/name 878 * jar:file://path!/name 879 * Where "path" is the bootstrap class path entry and "name" is the string 880 * passed into this method. "path" needs to be an absolute path (starting 881 * with '/'); if it's not we'd need to "absolutify" it as part of forming 882 * the URL string. 883 */ 884 StringObject* dvmGetBootPathResource(const char* name, int idx) 885 { 886 const int kUrlOverhead = 13; // worst case for Jar URL 887 const ClassPathEntry* cpe = gDvm.bootClassPath; 888 StringObject* urlObj = NULL; 889 890 ALOGV("+++ searching for resource '%s' in %d(%s)", 891 name, idx, cpe[idx].fileName); 892 893 /* we could use direct array index, but I don't entirely trust "idx" */ 894 while (idx-- && cpe->kind != kCpeLastEntry) 895 cpe++; 896 if (cpe->kind == kCpeLastEntry) { 897 assert(false); 898 return NULL; 899 } 900 901 char urlBuf[strlen(name) + strlen(cpe->fileName) + kUrlOverhead +1]; 902 903 switch (cpe->kind) { 904 case kCpeJar: 905 { 906 JarFile* pJarFile = (JarFile*) cpe->ptr; 907 if (dexZipFindEntry(&pJarFile->archive, name) == NULL) 908 goto bail; 909 sprintf(urlBuf, "jar:file://%s!/%s", cpe->fileName, name); 910 } 911 break; 912 case kCpeDex: 913 ALOGV("No resources in DEX files"); 914 goto bail; 915 default: 916 assert(false); 917 goto bail; 918 } 919 920 ALOGV("+++ using URL='%s'", urlBuf); 921 urlObj = dvmCreateStringFromCstr(urlBuf); 922 923 bail: 924 return urlObj; 925 } 926 927 928 /* 929 * =========================================================================== 930 * Class list management 931 * =========================================================================== 932 */ 933 934 /* search for these criteria in the Class hash table */ 935 struct ClassMatchCriteria { 936 const char* descriptor; 937 Object* loader; 938 }; 939 940 #define kInitLoaderInc 4 /* must be power of 2 */ 941 942 static InitiatingLoaderList *dvmGetInitiatingLoaderList(ClassObject* clazz) 943 { 944 assert(clazz->serialNumber >= INITIAL_CLASS_SERIAL_NUMBER); 945 int classIndex = clazz->serialNumber-INITIAL_CLASS_SERIAL_NUMBER; 946 if (gDvm.initiatingLoaderList != NULL && 947 classIndex < ZYGOTE_CLASS_CUTOFF) { 948 return &(gDvm.initiatingLoaderList[classIndex]); 949 } else { 950 return &(clazz->initiatingLoaderList); 951 } 952 } 953 954 /* 955 * Determine if "loader" appears in clazz' initiating loader list. 956 * 957 * The class hash table lock must be held when calling here, since 958 * it's also used when updating a class' initiating loader list. 959 * 960 * TODO: switch to some sort of lock-free data structure so we don't have 961 * to grab the lock to do a lookup. Among other things, this would improve 962 * the speed of compareDescriptorClasses(). 963 */ 964 bool dvmLoaderInInitiatingList(const ClassObject* clazz, const Object* loader) 965 { 966 /* 967 * The bootstrap class loader can't be just an initiating loader for 968 * anything (it's always the defining loader if the class is visible 969 * to it). We don't put defining loaders in the initiating list. 970 */ 971 if (loader == NULL) 972 return false; 973 974 /* 975 * Scan the list for a match. The list is expected to be short. 976 */ 977 /* Cast to remove the const from clazz, but use const loaderList */ 978 ClassObject* nonConstClazz = (ClassObject*) clazz; 979 const InitiatingLoaderList *loaderList = 980 dvmGetInitiatingLoaderList(nonConstClazz); 981 int i; 982 for (i = loaderList->initiatingLoaderCount-1; i >= 0; --i) { 983 if (loaderList->initiatingLoaders[i] == loader) { 984 //ALOGI("+++ found initiating match %p in %s", 985 // loader, clazz->descriptor); 986 return true; 987 } 988 } 989 return false; 990 } 991 992 /* 993 * Add "loader" to clazz's initiating loader set, unless it's the defining 994 * class loader. 995 * 996 * In the common case this will be a short list, so we don't need to do 997 * anything too fancy here. 998 * 999 * This locks gDvm.loadedClasses for synchronization, so don't hold it 1000 * when calling here. 1001 */ 1002 void dvmAddInitiatingLoader(ClassObject* clazz, Object* loader) 1003 { 1004 if (loader != clazz->classLoader) { 1005 assert(loader != NULL); 1006 1007 LOGVV("Adding %p to '%s' init list", loader, clazz->descriptor); 1008 dvmHashTableLock(gDvm.loadedClasses); 1009 1010 /* 1011 * Make sure nobody snuck in. The penalty for adding twice is 1012 * pretty minor, and probably outweighs the O(n^2) hit for 1013 * checking before every add, so we may not want to do this. 1014 */ 1015 //if (dvmLoaderInInitiatingList(clazz, loader)) { 1016 // ALOGW("WOW: simultaneous add of initiating class loader"); 1017 // goto bail_unlock; 1018 //} 1019 1020 /* 1021 * The list never shrinks, so we just keep a count of the 1022 * number of elements in it, and reallocate the buffer when 1023 * we run off the end. 1024 * 1025 * The pointer is initially NULL, so we *do* want to call realloc 1026 * when count==0. 1027 */ 1028 InitiatingLoaderList *loaderList = dvmGetInitiatingLoaderList(clazz); 1029 if ((loaderList->initiatingLoaderCount & (kInitLoaderInc-1)) == 0) { 1030 Object** newList; 1031 1032 newList = (Object**) realloc(loaderList->initiatingLoaders, 1033 (loaderList->initiatingLoaderCount + kInitLoaderInc) 1034 * sizeof(Object*)); 1035 if (newList == NULL) { 1036 /* this is mainly a cache, so it's not the EotW */ 1037 assert(false); 1038 goto bail_unlock; 1039 } 1040 loaderList->initiatingLoaders = newList; 1041 1042 //ALOGI("Expanded init list to %d (%s)", 1043 // loaderList->initiatingLoaderCount+kInitLoaderInc, 1044 // clazz->descriptor); 1045 } 1046 loaderList->initiatingLoaders[loaderList->initiatingLoaderCount++] = 1047 loader; 1048 1049 bail_unlock: 1050 dvmHashTableUnlock(gDvm.loadedClasses); 1051 } 1052 } 1053 1054 /* 1055 * (This is a dvmHashTableLookup callback.) 1056 * 1057 * Entries in the class hash table are stored as { descriptor, d-loader } 1058 * tuples. If the hashed class descriptor matches the requested descriptor, 1059 * and the hashed defining class loader matches the requested class 1060 * loader, we're good. If only the descriptor matches, we check to see if the 1061 * loader is in the hashed class' initiating loader list. If so, we 1062 * can return "true" immediately and skip some of the loadClass melodrama. 1063 * 1064 * The caller must lock the hash table before calling here. 1065 * 1066 * Returns 0 if a matching entry is found, nonzero otherwise. 1067 */ 1068 static int hashcmpClassByCrit(const void* vclazz, const void* vcrit) 1069 { 1070 const ClassObject* clazz = (const ClassObject*) vclazz; 1071 const ClassMatchCriteria* pCrit = (const ClassMatchCriteria*) vcrit; 1072 bool match; 1073 1074 match = (strcmp(clazz->descriptor, pCrit->descriptor) == 0 && 1075 (clazz->classLoader == pCrit->loader || 1076 (pCrit->loader != NULL && 1077 dvmLoaderInInitiatingList(clazz, pCrit->loader)) )); 1078 //if (match) 1079 // ALOGI("+++ %s %p matches existing %s %p", 1080 // pCrit->descriptor, pCrit->loader, 1081 // clazz->descriptor, clazz->classLoader); 1082 return !match; 1083 } 1084 1085 /* 1086 * Like hashcmpClassByCrit, but passing in a fully-formed ClassObject 1087 * instead of a ClassMatchCriteria. 1088 */ 1089 static int hashcmpClassByClass(const void* vclazz, const void* vaddclazz) 1090 { 1091 const ClassObject* clazz = (const ClassObject*) vclazz; 1092 const ClassObject* addClazz = (const ClassObject*) vaddclazz; 1093 bool match; 1094 1095 match = (strcmp(clazz->descriptor, addClazz->descriptor) == 0 && 1096 (clazz->classLoader == addClazz->classLoader || 1097 (addClazz->classLoader != NULL && 1098 dvmLoaderInInitiatingList(clazz, addClazz->classLoader)) )); 1099 return !match; 1100 } 1101 1102 /* 1103 * Search through the hash table to find an entry with a matching descriptor 1104 * and an initiating class loader that matches "loader". 1105 * 1106 * The table entries are hashed on descriptor only, because they're unique 1107 * on *defining* class loader, not *initiating* class loader. This isn't 1108 * great, because it guarantees we will have to probe when multiple 1109 * class loaders are used. 1110 * 1111 * Note this does NOT try to load a class; it just finds a class that 1112 * has already been loaded. 1113 * 1114 * If "unprepOkay" is set, this will return classes that have been added 1115 * to the hash table but are not yet fully loaded and linked. Otherwise, 1116 * such classes are ignored. (The only place that should set "unprepOkay" 1117 * is findClassNoInit(), which will wait for the prep to finish.) 1118 * 1119 * Returns NULL if not found. 1120 */ 1121 ClassObject* dvmLookupClass(const char* descriptor, Object* loader, 1122 bool unprepOkay) 1123 { 1124 ClassMatchCriteria crit; 1125 void* found; 1126 u4 hash; 1127 1128 crit.descriptor = descriptor; 1129 crit.loader = loader; 1130 hash = dvmComputeUtf8Hash(descriptor); 1131 1132 LOGVV("threadid=%d: dvmLookupClass searching for '%s' %p", 1133 dvmThreadSelf()->threadId, descriptor, loader); 1134 1135 dvmHashTableLock(gDvm.loadedClasses); 1136 found = dvmHashTableLookup(gDvm.loadedClasses, hash, &crit, 1137 hashcmpClassByCrit, false); 1138 dvmHashTableUnlock(gDvm.loadedClasses); 1139 1140 /* 1141 * The class has been added to the hash table but isn't ready for use. 1142 * We're going to act like we didn't see it, so that the caller will 1143 * go through the full "find class" path, which includes locking the 1144 * object and waiting until it's ready. We could do that lock/wait 1145 * here, but this is an extremely rare case, and it's simpler to have 1146 * the wait-for-class code centralized. 1147 */ 1148 if (found && !unprepOkay && !dvmIsClassLinked((ClassObject*)found)) { 1149 ALOGV("Ignoring not-yet-ready %s, using slow path", 1150 ((ClassObject*)found)->descriptor); 1151 found = NULL; 1152 } 1153 1154 return (ClassObject*) found; 1155 } 1156 1157 /* 1158 * Add a new class to the hash table. 1159 * 1160 * The class is considered "new" if it doesn't match on both the class 1161 * descriptor and the defining class loader. 1162 * 1163 * TODO: we should probably have separate hash tables for each 1164 * ClassLoader. This could speed up dvmLookupClass and 1165 * other common operations. It does imply a VM-visible data structure 1166 * for each ClassLoader object with loaded classes, which we don't 1167 * have yet. 1168 */ 1169 bool dvmAddClassToHash(ClassObject* clazz) 1170 { 1171 void* found; 1172 u4 hash; 1173 1174 hash = dvmComputeUtf8Hash(clazz->descriptor); 1175 1176 dvmHashTableLock(gDvm.loadedClasses); 1177 found = dvmHashTableLookup(gDvm.loadedClasses, hash, clazz, 1178 hashcmpClassByClass, true); 1179 dvmHashTableUnlock(gDvm.loadedClasses); 1180 1181 ALOGV("+++ dvmAddClassToHash '%s' %p (isnew=%d) --> %p", 1182 clazz->descriptor, clazz->classLoader, 1183 (found == (void*) clazz), clazz); 1184 1185 //dvmCheckClassTablePerf(); 1186 1187 /* can happen if two threads load the same class simultaneously */ 1188 return (found == (void*) clazz); 1189 } 1190 1191 #if 0 1192 /* 1193 * Compute hash value for a class. 1194 */ 1195 u4 hashcalcClass(const void* item) 1196 { 1197 return dvmComputeUtf8Hash(((const ClassObject*) item)->descriptor); 1198 } 1199 1200 /* 1201 * Check the performance of the "loadedClasses" hash table. 1202 */ 1203 void dvmCheckClassTablePerf() 1204 { 1205 dvmHashTableLock(gDvm.loadedClasses); 1206 dvmHashTableProbeCount(gDvm.loadedClasses, hashcalcClass, 1207 hashcmpClassByClass); 1208 dvmHashTableUnlock(gDvm.loadedClasses); 1209 } 1210 #endif 1211 1212 /* 1213 * Remove a class object from the hash table. 1214 */ 1215 static void removeClassFromHash(ClassObject* clazz) 1216 { 1217 ALOGV("+++ removeClassFromHash '%s'", clazz->descriptor); 1218 1219 u4 hash = dvmComputeUtf8Hash(clazz->descriptor); 1220 1221 dvmHashTableLock(gDvm.loadedClasses); 1222 if (!dvmHashTableRemove(gDvm.loadedClasses, hash, clazz)) 1223 ALOGW("Hash table remove failed on class '%s'", clazz->descriptor); 1224 dvmHashTableUnlock(gDvm.loadedClasses); 1225 } 1226 1227 1228 /* 1229 * =========================================================================== 1230 * Class creation 1231 * =========================================================================== 1232 */ 1233 1234 /* 1235 * Set clazz->serialNumber to the next available value. 1236 * 1237 * This usually happens *very* early in class creation, so don't expect 1238 * anything else in the class to be ready. 1239 */ 1240 void dvmSetClassSerialNumber(ClassObject* clazz) 1241 { 1242 assert(clazz->serialNumber == 0); 1243 clazz->serialNumber = android_atomic_inc(&gDvm.classSerialNumber); 1244 } 1245 1246 1247 /* 1248 * Find the named class (by descriptor), using the specified 1249 * initiating ClassLoader. 1250 * 1251 * The class will be loaded and initialized if it has not already been. 1252 * If necessary, the superclass will be loaded. 1253 * 1254 * If the class can't be found, returns NULL with an appropriate exception 1255 * raised. 1256 */ 1257 ClassObject* dvmFindClass(const char* descriptor, Object* loader) 1258 { 1259 ClassObject* clazz; 1260 1261 clazz = dvmFindClassNoInit(descriptor, loader); 1262 if (clazz != NULL && clazz->status < CLASS_INITIALIZED) { 1263 /* initialize class */ 1264 if (!dvmInitClass(clazz)) { 1265 /* init failed; leave it in the list, marked as bad */ 1266 assert(dvmCheckException(dvmThreadSelf())); 1267 assert(clazz->status == CLASS_ERROR); 1268 return NULL; 1269 } 1270 } 1271 1272 return clazz; 1273 } 1274 1275 /* 1276 * Find the named class (by descriptor), using the specified 1277 * initiating ClassLoader. 1278 * 1279 * The class will be loaded if it has not already been, as will its 1280 * superclass. It will not be initialized. 1281 * 1282 * If the class can't be found, returns NULL with an appropriate exception 1283 * raised. 1284 */ 1285 ClassObject* dvmFindClassNoInit(const char* descriptor, 1286 Object* loader) 1287 { 1288 assert(descriptor != NULL); 1289 //assert(loader != NULL); 1290 1291 LOGVV("FindClassNoInit '%s' %p", descriptor, loader); 1292 1293 if (*descriptor == '[') { 1294 /* 1295 * Array class. Find in table, generate if not found. 1296 */ 1297 return dvmFindArrayClass(descriptor, loader); 1298 } else { 1299 /* 1300 * Regular class. Find in table, load if not found. 1301 */ 1302 if (loader != NULL) { 1303 return findClassFromLoaderNoInit(descriptor, loader); 1304 } else { 1305 return dvmFindSystemClassNoInit(descriptor); 1306 } 1307 } 1308 } 1309 1310 /* 1311 * Load the named class (by descriptor) from the specified class 1312 * loader. This calls out to let the ClassLoader object do its thing. 1313 * 1314 * Returns with NULL and an exception raised on error. 1315 */ 1316 static ClassObject* findClassFromLoaderNoInit(const char* descriptor, 1317 Object* loader) 1318 { 1319 //ALOGI("##### findClassFromLoaderNoInit (%s,%p)", 1320 // descriptor, loader); 1321 1322 Thread* self = dvmThreadSelf(); 1323 1324 assert(loader != NULL); 1325 1326 /* 1327 * Do we already have it? 1328 * 1329 * The class loader code does the "is it already loaded" check as 1330 * well. However, this call is much faster than calling through 1331 * interpreted code. Doing this does mean that in the common case 1332 * (365 out of 420 calls booting the sim) we're doing the 1333 * lookup-by-descriptor twice. It appears this is still a win, so 1334 * I'm keeping it in. 1335 */ 1336 ClassObject* clazz = dvmLookupClass(descriptor, loader, false); 1337 if (clazz != NULL) { 1338 LOGVV("Already loaded: %s %p", descriptor, loader); 1339 return clazz; 1340 } else { 1341 LOGVV("Not already loaded: %s %p", descriptor, loader); 1342 } 1343 1344 char* dotName = NULL; 1345 StringObject* nameObj = NULL; 1346 1347 /* convert "Landroid/debug/Stuff;" to "android.debug.Stuff" */ 1348 dotName = dvmDescriptorToDot(descriptor); 1349 if (dotName == NULL) { 1350 dvmThrowOutOfMemoryError(NULL); 1351 return NULL; 1352 } 1353 nameObj = dvmCreateStringFromCstr(dotName); 1354 if (nameObj == NULL) { 1355 assert(dvmCheckException(self)); 1356 goto bail; 1357 } 1358 1359 dvmMethodTraceClassPrepBegin(); 1360 1361 /* 1362 * Invoke loadClass(). This will probably result in a couple of 1363 * exceptions being thrown, because the ClassLoader.loadClass() 1364 * implementation eventually calls VMClassLoader.loadClass to see if 1365 * the bootstrap class loader can find it before doing its own load. 1366 */ 1367 LOGVV("--- Invoking loadClass(%s, %p)", dotName, loader); 1368 { 1369 const Method* loadClass = 1370 loader->clazz->vtable[gDvm.voffJavaLangClassLoader_loadClass]; 1371 JValue result; 1372 dvmCallMethod(self, loadClass, loader, &result, nameObj); 1373 clazz = (ClassObject*) result.l; 1374 1375 dvmMethodTraceClassPrepEnd(); 1376 Object* excep = dvmGetException(self); 1377 if (excep != NULL) { 1378 #if DVM_SHOW_EXCEPTION >= 2 1379 ALOGD("NOTE: loadClass '%s' %p threw exception %s", 1380 dotName, loader, excep->clazz->descriptor); 1381 #endif 1382 dvmAddTrackedAlloc(excep, self); 1383 dvmClearException(self); 1384 dvmThrowChainedNoClassDefFoundError(descriptor, excep); 1385 dvmReleaseTrackedAlloc(excep, self); 1386 clazz = NULL; 1387 goto bail; 1388 } else if (clazz == NULL) { 1389 ALOGW("ClassLoader returned NULL w/o exception pending"); 1390 dvmThrowNullPointerException("ClassLoader returned null"); 1391 goto bail; 1392 } 1393 } 1394 1395 /* not adding clazz to tracked-alloc list, because it's a ClassObject */ 1396 1397 dvmAddInitiatingLoader(clazz, loader); 1398 1399 LOGVV("--- Successfully loaded %s %p (thisldr=%p clazz=%p)", 1400 descriptor, clazz->classLoader, loader, clazz); 1401 1402 bail: 1403 dvmReleaseTrackedAlloc((Object*)nameObj, NULL); 1404 free(dotName); 1405 return clazz; 1406 } 1407 1408 /* 1409 * Load the named class (by descriptor) from the specified DEX file. 1410 * Used by class loaders to instantiate a class object from a 1411 * VM-managed DEX. 1412 */ 1413 ClassObject* dvmDefineClass(DvmDex* pDvmDex, const char* descriptor, 1414 Object* classLoader) 1415 { 1416 assert(pDvmDex != NULL); 1417 1418 return findClassNoInit(descriptor, classLoader, pDvmDex); 1419 } 1420 1421 1422 /* 1423 * Find the named class (by descriptor), scanning through the 1424 * bootclasspath if it hasn't already been loaded. 1425 * 1426 * "descriptor" looks like "Landroid/debug/Stuff;". 1427 * 1428 * Uses NULL as the defining class loader. 1429 */ 1430 ClassObject* dvmFindSystemClass(const char* descriptor) 1431 { 1432 ClassObject* clazz; 1433 1434 clazz = dvmFindSystemClassNoInit(descriptor); 1435 if (clazz != NULL && clazz->status < CLASS_INITIALIZED) { 1436 /* initialize class */ 1437 if (!dvmInitClass(clazz)) { 1438 /* init failed; leave it in the list, marked as bad */ 1439 assert(dvmCheckException(dvmThreadSelf())); 1440 assert(clazz->status == CLASS_ERROR); 1441 return NULL; 1442 } 1443 } 1444 1445 return clazz; 1446 } 1447 1448 /* 1449 * Find the named class (by descriptor), searching for it in the 1450 * bootclasspath. 1451 * 1452 * On failure, this returns NULL with an exception raised. 1453 */ 1454 ClassObject* dvmFindSystemClassNoInit(const char* descriptor) 1455 { 1456 return findClassNoInit(descriptor, NULL, NULL); 1457 } 1458 1459 /* 1460 * Find the named class (by descriptor). If it's not already loaded, 1461 * we load it and link it, but don't execute <clinit>. (The VM has 1462 * specific limitations on which events can cause initialization.) 1463 * 1464 * If "pDexFile" is NULL, we will search the bootclasspath for an entry. 1465 * 1466 * On failure, this returns NULL with an exception raised. 1467 * 1468 * TODO: we need to return an indication of whether we loaded the class or 1469 * used an existing definition. If somebody deliberately tries to load a 1470 * class twice in the same class loader, they should get a LinkageError, 1471 * but inadvertent simultaneous class references should "just work". 1472 */ 1473 static ClassObject* findClassNoInit(const char* descriptor, Object* loader, 1474 DvmDex* pDvmDex) 1475 { 1476 Thread* self = dvmThreadSelf(); 1477 ClassObject* clazz; 1478 bool profilerNotified = false; 1479 1480 if (loader != NULL) { 1481 LOGVV("#### findClassNoInit(%s,%p,%p)", descriptor, loader, 1482 pDvmDex->pDexFile); 1483 } 1484 1485 /* 1486 * We don't expect an exception to be raised at this point. The 1487 * exception handling code is good about managing this. This *can* 1488 * happen if a JNI lookup fails and the JNI code doesn't do any 1489 * error checking before doing another class lookup, so we may just 1490 * want to clear this and restore it on exit. If we don't, some kinds 1491 * of failures can't be detected without rearranging other stuff. 1492 * 1493 * Most often when we hit this situation it means that something is 1494 * broken in the VM or in JNI code, so I'm keeping it in place (and 1495 * making it an informative abort rather than an assert). 1496 */ 1497 if (dvmCheckException(self)) { 1498 ALOGE("Class lookup %s attempted with exception pending", descriptor); 1499 ALOGW("Pending exception is:"); 1500 dvmLogExceptionStackTrace(); 1501 dvmDumpAllThreads(false); 1502 dvmAbort(); 1503 } 1504 1505 clazz = dvmLookupClass(descriptor, loader, true); 1506 if (clazz == NULL) { 1507 const DexClassDef* pClassDef; 1508 1509 dvmMethodTraceClassPrepBegin(); 1510 profilerNotified = true; 1511 1512 #if LOG_CLASS_LOADING 1513 u8 startTime = dvmGetThreadCpuTimeNsec(); 1514 #endif 1515 1516 if (pDvmDex == NULL) { 1517 assert(loader == NULL); /* shouldn't be here otherwise */ 1518 pDvmDex = searchBootPathForClass(descriptor, &pClassDef); 1519 } else { 1520 pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor); 1521 } 1522 1523 if (pDvmDex == NULL || pClassDef == NULL) { 1524 if (gDvm.noClassDefFoundErrorObj != NULL) { 1525 /* usual case -- use prefabricated object */ 1526 dvmSetException(self, gDvm.noClassDefFoundErrorObj); 1527 } else { 1528 /* dexopt case -- can't guarantee prefab (core.jar) */ 1529 dvmThrowNoClassDefFoundError(descriptor); 1530 } 1531 goto bail; 1532 } 1533 1534 /* found a match, try to load it */ 1535 clazz = loadClassFromDex(pDvmDex, pClassDef, loader); 1536 if (dvmCheckException(self)) { 1537 /* class was found but had issues */ 1538 if (clazz != NULL) { 1539 dvmFreeClassInnards(clazz); 1540 dvmReleaseTrackedAlloc((Object*) clazz, NULL); 1541 } 1542 goto bail; 1543 } 1544 1545 /* 1546 * Lock the class while we link it so other threads must wait for us 1547 * to finish. Set the "initThreadId" so we can identify recursive 1548 * invocation. (Note all accesses to initThreadId here are 1549 * guarded by the class object's lock.) 1550 */ 1551 dvmLockObject(self, (Object*) clazz); 1552 clazz->initThreadId = self->threadId; 1553 1554 /* 1555 * Add to hash table so lookups succeed. 1556 * 1557 * [Are circular references possible when linking a class?] 1558 */ 1559 assert(clazz->classLoader == loader); 1560 if (!dvmAddClassToHash(clazz)) { 1561 /* 1562 * Another thread must have loaded the class after we 1563 * started but before we finished. Discard what we've 1564 * done and leave some hints for the GC. 1565 * 1566 * (Yes, this happens.) 1567 */ 1568 //ALOGW("WOW: somebody loaded %s simultaneously", descriptor); 1569 clazz->initThreadId = 0; 1570 dvmUnlockObject(self, (Object*) clazz); 1571 1572 /* Let the GC free the class. 1573 */ 1574 dvmFreeClassInnards(clazz); 1575 dvmReleaseTrackedAlloc((Object*) clazz, NULL); 1576 1577 /* Grab the winning class. 1578 */ 1579 clazz = dvmLookupClass(descriptor, loader, true); 1580 assert(clazz != NULL); 1581 goto got_class; 1582 } 1583 dvmReleaseTrackedAlloc((Object*) clazz, NULL); 1584 1585 #if LOG_CLASS_LOADING 1586 logClassLoadWithTime('>', clazz, startTime); 1587 #endif 1588 /* 1589 * Prepare and resolve. 1590 */ 1591 if (!dvmLinkClass(clazz)) { 1592 assert(dvmCheckException(self)); 1593 1594 /* Make note of the error and clean up the class. 1595 */ 1596 removeClassFromHash(clazz); 1597 clazz->status = CLASS_ERROR; 1598 dvmFreeClassInnards(clazz); 1599 1600 /* Let any waiters know. 1601 */ 1602 clazz->initThreadId = 0; 1603 dvmObjectNotifyAll(self, (Object*) clazz); 1604 dvmUnlockObject(self, (Object*) clazz); 1605 1606 #if LOG_CLASS_LOADING 1607 ALOG(LOG_INFO, "DVMLINK FAILED FOR CLASS ", "%s in %s", 1608 clazz->descriptor, get_process_name()); 1609 1610 /* 1611 * TODO: It would probably be better to use a new type code here (instead of '<') to 1612 * indicate the failure. This change would require a matching change in the parser 1613 * and analysis code in frameworks/base/tools/preload. 1614 */ 1615 logClassLoad('<', clazz); 1616 #endif 1617 clazz = NULL; 1618 if (gDvm.optimizing) { 1619 /* happens with "external" libs */ 1620 ALOGV("Link of class '%s' failed", descriptor); 1621 } else { 1622 ALOGW("Link of class '%s' failed", descriptor); 1623 } 1624 goto bail; 1625 } 1626 dvmObjectNotifyAll(self, (Object*) clazz); 1627 dvmUnlockObject(self, (Object*) clazz); 1628 1629 /* 1630 * Add class stats to global counters. 1631 * 1632 * TODO: these should probably be atomic ops. 1633 */ 1634 gDvm.numLoadedClasses++; 1635 gDvm.numDeclaredMethods += 1636 clazz->virtualMethodCount + clazz->directMethodCount; 1637 gDvm.numDeclaredInstFields += clazz->ifieldCount; 1638 gDvm.numDeclaredStaticFields += clazz->sfieldCount; 1639 1640 /* 1641 * Cache pointers to basic classes. We want to use these in 1642 * various places, and it's easiest to initialize them on first 1643 * use rather than trying to force them to initialize (startup 1644 * ordering makes it weird). 1645 */ 1646 if (gDvm.classJavaLangObject == NULL && 1647 strcmp(descriptor, "Ljava/lang/Object;") == 0) 1648 { 1649 /* It should be impossible to get here with anything 1650 * but the bootclasspath loader. 1651 */ 1652 assert(loader == NULL); 1653 gDvm.classJavaLangObject = clazz; 1654 } 1655 1656 #if LOG_CLASS_LOADING 1657 logClassLoad('<', clazz); 1658 #endif 1659 1660 } else { 1661 got_class: 1662 if (!dvmIsClassLinked(clazz) && clazz->status != CLASS_ERROR) { 1663 /* 1664 * We can race with other threads for class linking. We should 1665 * never get here recursively; doing so indicates that two 1666 * classes have circular dependencies. 1667 * 1668 * One exception: we force discovery of java.lang.Class in 1669 * dvmLinkClass(), and Class has Object as its superclass. So 1670 * if the first thing we ever load is Object, we will init 1671 * Object->Class->Object. The easiest way to avoid this is to 1672 * ensure that Object is never the first thing we look up, so 1673 * we get Foo->Class->Object instead. 1674 */ 1675 dvmLockObject(self, (Object*) clazz); 1676 if (!dvmIsClassLinked(clazz) && 1677 clazz->initThreadId == self->threadId) 1678 { 1679 ALOGW("Recursive link on class %s", clazz->descriptor); 1680 dvmUnlockObject(self, (Object*) clazz); 1681 dvmThrowClassCircularityError(clazz->descriptor); 1682 clazz = NULL; 1683 goto bail; 1684 } 1685 //ALOGI("WAITING for '%s' (owner=%d)", 1686 // clazz->descriptor, clazz->initThreadId); 1687 while (!dvmIsClassLinked(clazz) && clazz->status != CLASS_ERROR) { 1688 dvmObjectWait(self, (Object*) clazz, 0, 0, false); 1689 } 1690 dvmUnlockObject(self, (Object*) clazz); 1691 } 1692 if (clazz->status == CLASS_ERROR) { 1693 /* 1694 * Somebody else tried to load this and failed. We need to raise 1695 * an exception and report failure. 1696 */ 1697 throwEarlierClassFailure(clazz); 1698 clazz = NULL; 1699 goto bail; 1700 } 1701 } 1702 1703 /* check some invariants */ 1704 assert(dvmIsClassLinked(clazz)); 1705 assert(gDvm.classJavaLangClass != NULL); 1706 assert(clazz->clazz == gDvm.classJavaLangClass); 1707 assert(dvmIsClassObject(clazz)); 1708 assert(clazz == gDvm.classJavaLangObject || clazz->super != NULL); 1709 if (!dvmIsInterfaceClass(clazz)) { 1710 //ALOGI("class=%s vtableCount=%d, virtualMeth=%d", 1711 // clazz->descriptor, clazz->vtableCount, 1712 // clazz->virtualMethodCount); 1713 assert(clazz->vtableCount >= clazz->virtualMethodCount); 1714 } 1715 1716 bail: 1717 if (profilerNotified) 1718 dvmMethodTraceClassPrepEnd(); 1719 assert(clazz != NULL || dvmCheckException(self)); 1720 return clazz; 1721 } 1722 1723 /* 1724 * Helper for loadClassFromDex, which takes a DexClassDataHeader and 1725 * encoded data pointer in addition to the other arguments. 1726 */ 1727 static ClassObject* loadClassFromDex0(DvmDex* pDvmDex, 1728 const DexClassDef* pClassDef, const DexClassDataHeader* pHeader, 1729 const u1* pEncodedData, Object* classLoader) 1730 { 1731 ClassObject* newClass = NULL; 1732 const DexFile* pDexFile; 1733 const char* descriptor; 1734 int i; 1735 1736 pDexFile = pDvmDex->pDexFile; 1737 descriptor = dexGetClassDescriptor(pDexFile, pClassDef); 1738 1739 /* 1740 * Make sure the aren't any "bonus" flags set, since we use them for 1741 * runtime state. 1742 */ 1743 /* bits we can reasonably expect to see set in a DEX access flags field */ 1744 const uint32_t EXPECTED_FILE_FLAGS = (ACC_CLASS_MASK | CLASS_ISPREVERIFIED | 1745 CLASS_ISOPTIMIZED); 1746 if ((pClassDef->accessFlags & ~EXPECTED_FILE_FLAGS) != 0) { 1747 ALOGW("Invalid file flags in class %s: %04x", 1748 descriptor, pClassDef->accessFlags); 1749 return NULL; 1750 } 1751 1752 /* 1753 * Allocate storage for the class object on the GC heap, so that other 1754 * objects can have references to it. We bypass the usual mechanism 1755 * (allocObject), because we don't have all the bits and pieces yet. 1756 * 1757 * Note that we assume that java.lang.Class does not override 1758 * finalize(). 1759 */ 1760 /* TODO: Can there be fewer special checks in the usual path? */ 1761 assert(descriptor != NULL); 1762 if (classLoader == NULL && 1763 strcmp(descriptor, "Ljava/lang/Class;") == 0) { 1764 assert(gDvm.classJavaLangClass != NULL); 1765 newClass = gDvm.classJavaLangClass; 1766 } else { 1767 size_t size = classObjectSize(pHeader->staticFieldsSize); 1768 newClass = (ClassObject*) dvmMalloc(size, ALLOC_NON_MOVING); 1769 } 1770 if (newClass == NULL) 1771 return NULL; 1772 1773 DVM_OBJECT_INIT(newClass, gDvm.classJavaLangClass); 1774 dvmSetClassSerialNumber(newClass); 1775 newClass->descriptor = descriptor; 1776 assert(newClass->descriptorAlloc == NULL); 1777 SET_CLASS_FLAG(newClass, pClassDef->accessFlags); 1778 dvmSetFieldObject((Object *)newClass, 1779 OFFSETOF_MEMBER(ClassObject, classLoader), 1780 (Object *)classLoader); 1781 newClass->pDvmDex = pDvmDex; 1782 newClass->primitiveType = PRIM_NOT; 1783 newClass->status = CLASS_IDX; 1784 1785 /* 1786 * Stuff the superclass index into the object pointer field. The linker 1787 * pulls it out and replaces it with a resolved ClassObject pointer. 1788 * I'm doing it this way (rather than having a dedicated superclassIdx 1789 * field) to save a few bytes of overhead per class. 1790 * 1791 * newClass->super is not traversed or freed by dvmFreeClassInnards, so 1792 * this is safe. 1793 */ 1794 assert(sizeof(u4) == sizeof(ClassObject*)); /* 32-bit check */ 1795 newClass->super = (ClassObject*) pClassDef->superclassIdx; 1796 1797 /* 1798 * Stuff class reference indices into the pointer fields. 1799 * 1800 * The elements of newClass->interfaces are not traversed or freed by 1801 * dvmFreeClassInnards, so this is GC-safe. 1802 */ 1803 const DexTypeList* pInterfacesList; 1804 pInterfacesList = dexGetInterfacesList(pDexFile, pClassDef); 1805 if (pInterfacesList != NULL) { 1806 newClass->interfaceCount = pInterfacesList->size; 1807 newClass->interfaces = (ClassObject**) dvmLinearAlloc(classLoader, 1808 newClass->interfaceCount * sizeof(ClassObject*)); 1809 1810 for (i = 0; i < newClass->interfaceCount; i++) { 1811 const DexTypeItem* pType = dexGetTypeItem(pInterfacesList, i); 1812 newClass->interfaces[i] = (ClassObject*)(u4) pType->typeIdx; 1813 } 1814 dvmLinearReadOnly(classLoader, newClass->interfaces); 1815 } 1816 1817 /* load field definitions */ 1818 1819 /* 1820 * Over-allocate the class object and append static field info 1821 * onto the end. It's fixed-size and known at alloc time. This 1822 * seems to increase zygote sharing. Heap compaction will have to 1823 * be careful if it ever tries to move ClassObject instances, 1824 * because we pass Field pointers around internally. But at least 1825 * now these Field pointers are in the object heap. 1826 */ 1827 1828 if (pHeader->staticFieldsSize != 0) { 1829 /* static fields stay on system heap; field data isn't "write once" */ 1830 int count = (int) pHeader->staticFieldsSize; 1831 u4 lastIndex = 0; 1832 DexField field; 1833 1834 newClass->sfieldCount = count; 1835 for (i = 0; i < count; i++) { 1836 dexReadClassDataField(&pEncodedData, &field, &lastIndex); 1837 loadSFieldFromDex(newClass, &field, &newClass->sfields[i]); 1838 } 1839 } 1840 1841 if (pHeader->instanceFieldsSize != 0) { 1842 int count = (int) pHeader->instanceFieldsSize; 1843 u4 lastIndex = 0; 1844 DexField field; 1845 1846 newClass->ifieldCount = count; 1847 newClass->ifields = (InstField*) dvmLinearAlloc(classLoader, 1848 count * sizeof(InstField)); 1849 for (i = 0; i < count; i++) { 1850 dexReadClassDataField(&pEncodedData, &field, &lastIndex); 1851 loadIFieldFromDex(newClass, &field, &newClass->ifields[i]); 1852 } 1853 dvmLinearReadOnly(classLoader, newClass->ifields); 1854 } 1855 1856 /* 1857 * Load method definitions. We do this in two batches, direct then 1858 * virtual. 1859 * 1860 * If register maps have already been generated for this class, and 1861 * precise GC is enabled, we pull out pointers to them. We know that 1862 * they were streamed to the DEX file in the same order in which the 1863 * methods appear. 1864 * 1865 * If the class wasn't pre-verified, the maps will be generated when 1866 * the class is verified during class initialization. 1867 */ 1868 u4 classDefIdx = dexGetIndexForClassDef(pDexFile, pClassDef); 1869 const void* classMapData; 1870 u4 numMethods; 1871 1872 if (gDvm.preciseGc) { 1873 classMapData = 1874 dvmRegisterMapGetClassData(pDexFile, classDefIdx, &numMethods); 1875 1876 /* sanity check */ 1877 if (classMapData != NULL && 1878 pHeader->directMethodsSize + pHeader->virtualMethodsSize != numMethods) 1879 { 1880 ALOGE("ERROR: in %s, direct=%d virtual=%d, maps have %d", 1881 newClass->descriptor, pHeader->directMethodsSize, 1882 pHeader->virtualMethodsSize, numMethods); 1883 assert(false); 1884 classMapData = NULL; /* abandon */ 1885 } 1886 } else { 1887 classMapData = NULL; 1888 } 1889 1890 if (pHeader->directMethodsSize != 0) { 1891 int count = (int) pHeader->directMethodsSize; 1892 u4 lastIndex = 0; 1893 DexMethod method; 1894 1895 newClass->directMethodCount = count; 1896 newClass->directMethods = (Method*) dvmLinearAlloc(classLoader, 1897 count * sizeof(Method)); 1898 for (i = 0; i < count; i++) { 1899 dexReadClassDataMethod(&pEncodedData, &method, &lastIndex); 1900 loadMethodFromDex(newClass, &method, &newClass->directMethods[i]); 1901 if (classMapData != NULL) { 1902 const RegisterMap* pMap = dvmRegisterMapGetNext(&classMapData); 1903 if (dvmRegisterMapGetFormat(pMap) != kRegMapFormatNone) { 1904 newClass->directMethods[i].registerMap = pMap; 1905 /* TODO: add rigorous checks */ 1906 assert((newClass->directMethods[i].registersSize+7) / 8 == 1907 newClass->directMethods[i].registerMap->regWidth); 1908 } 1909 } 1910 } 1911 dvmLinearReadOnly(classLoader, newClass->directMethods); 1912 } 1913 1914 if (pHeader->virtualMethodsSize != 0) { 1915 int count = (int) pHeader->virtualMethodsSize; 1916 u4 lastIndex = 0; 1917 DexMethod method; 1918 1919 newClass->virtualMethodCount = count; 1920 newClass->virtualMethods = (Method*) dvmLinearAlloc(classLoader, 1921 count * sizeof(Method)); 1922 for (i = 0; i < count; i++) { 1923 dexReadClassDataMethod(&pEncodedData, &method, &lastIndex); 1924 loadMethodFromDex(newClass, &method, &newClass->virtualMethods[i]); 1925 if (classMapData != NULL) { 1926 const RegisterMap* pMap = dvmRegisterMapGetNext(&classMapData); 1927 if (dvmRegisterMapGetFormat(pMap) != kRegMapFormatNone) { 1928 newClass->virtualMethods[i].registerMap = pMap; 1929 /* TODO: add rigorous checks */ 1930 assert((newClass->virtualMethods[i].registersSize+7) / 8 == 1931 newClass->virtualMethods[i].registerMap->regWidth); 1932 } 1933 } 1934 } 1935 dvmLinearReadOnly(classLoader, newClass->virtualMethods); 1936 } 1937 1938 newClass->sourceFile = dexGetSourceFile(pDexFile, pClassDef); 1939 1940 /* caller must call dvmReleaseTrackedAlloc */ 1941 return newClass; 1942 } 1943 1944 /* 1945 * Try to load the indicated class from the specified DEX file. 1946 * 1947 * This is effectively loadClass()+defineClass() for a DexClassDef. The 1948 * loading was largely done when we crunched through the DEX. 1949 * 1950 * Returns NULL on failure. If we locate the class but encounter an error 1951 * while processing it, an appropriate exception is thrown. 1952 */ 1953 static ClassObject* loadClassFromDex(DvmDex* pDvmDex, 1954 const DexClassDef* pClassDef, Object* classLoader) 1955 { 1956 ClassObject* result; 1957 DexClassDataHeader header; 1958 const u1* pEncodedData; 1959 const DexFile* pDexFile; 1960 1961 assert((pDvmDex != NULL) && (pClassDef != NULL)); 1962 pDexFile = pDvmDex->pDexFile; 1963 1964 if (gDvm.verboseClass) { 1965 ALOGV("CLASS: loading '%s'...", 1966 dexGetClassDescriptor(pDexFile, pClassDef)); 1967 } 1968 1969 pEncodedData = dexGetClassData(pDexFile, pClassDef); 1970 1971 if (pEncodedData != NULL) { 1972 dexReadClassDataHeader(&pEncodedData, &header); 1973 } else { 1974 // Provide an all-zeroes header for the rest of the loading. 1975 memset(&header, 0, sizeof(header)); 1976 } 1977 1978 result = loadClassFromDex0(pDvmDex, pClassDef, &header, pEncodedData, 1979 classLoader); 1980 1981 if (gDvm.verboseClass && (result != NULL)) { 1982 ALOGI("[Loaded %s from DEX %p (cl=%p)]", 1983 result->descriptor, pDvmDex, classLoader); 1984 } 1985 1986 return result; 1987 } 1988 1989 /* 1990 * Free anything in a ClassObject that was allocated on the system heap. 1991 * 1992 * The ClassObject itself is allocated on the GC heap, so we leave it for 1993 * the garbage collector. 1994 * 1995 * NOTE: this may be called with a partially-constructed object. 1996 * NOTE: there is no particular ordering imposed, so don't go poking at 1997 * superclasses. 1998 */ 1999 void dvmFreeClassInnards(ClassObject* clazz) 2000 { 2001 void *tp; 2002 int i; 2003 2004 if (clazz == NULL) 2005 return; 2006 2007 assert(clazz->clazz == gDvm.classJavaLangClass); 2008 assert(dvmIsClassObject(clazz)); 2009 2010 /* Guarantee that dvmFreeClassInnards can be called on a given 2011 * class multiple times by clearing things out as we free them. 2012 * We don't make any attempt at real atomicity here; higher 2013 * levels need to make sure that no two threads can free the 2014 * same ClassObject at the same time. 2015 * 2016 * TODO: maybe just make it so the GC will never free the 2017 * innards of an already-freed class. 2018 * 2019 * TODO: this #define isn't MT-safe -- the compiler could rearrange it. 2020 */ 2021 #define NULL_AND_FREE(p) \ 2022 do { \ 2023 if ((p) != NULL) { \ 2024 tp = (p); \ 2025 (p) = NULL; \ 2026 free(tp); \ 2027 } \ 2028 } while (0) 2029 #define NULL_AND_LINEAR_FREE(p) \ 2030 do { \ 2031 if ((p) != NULL) { \ 2032 tp = (p); \ 2033 (p) = NULL; \ 2034 dvmLinearFree(clazz->classLoader, tp); \ 2035 } \ 2036 } while (0) 2037 2038 /* arrays just point at Object's vtable; don't free vtable in this case. 2039 */ 2040 clazz->vtableCount = -1; 2041 if (clazz->vtable == gDvm.classJavaLangObject->vtable) { 2042 clazz->vtable = NULL; 2043 } else { 2044 NULL_AND_LINEAR_FREE(clazz->vtable); 2045 } 2046 2047 clazz->descriptor = NULL; 2048 NULL_AND_FREE(clazz->descriptorAlloc); 2049 2050 if (clazz->directMethods != NULL) { 2051 Method *directMethods = clazz->directMethods; 2052 int directMethodCount = clazz->directMethodCount; 2053 clazz->directMethods = NULL; 2054 clazz->directMethodCount = -1; 2055 dvmLinearReadWrite(clazz->classLoader, directMethods); 2056 for (i = 0; i < directMethodCount; i++) { 2057 freeMethodInnards(&directMethods[i]); 2058 } 2059 dvmLinearReadOnly(clazz->classLoader, directMethods); 2060 dvmLinearFree(clazz->classLoader, directMethods); 2061 } 2062 if (clazz->virtualMethods != NULL) { 2063 Method *virtualMethods = clazz->virtualMethods; 2064 int virtualMethodCount = clazz->virtualMethodCount; 2065 clazz->virtualMethodCount = -1; 2066 clazz->virtualMethods = NULL; 2067 dvmLinearReadWrite(clazz->classLoader, virtualMethods); 2068 for (i = 0; i < virtualMethodCount; i++) { 2069 freeMethodInnards(&virtualMethods[i]); 2070 } 2071 dvmLinearReadOnly(clazz->classLoader, virtualMethods); 2072 dvmLinearFree(clazz->classLoader, virtualMethods); 2073 } 2074 2075 InitiatingLoaderList *loaderList = dvmGetInitiatingLoaderList(clazz); 2076 loaderList->initiatingLoaderCount = -1; 2077 NULL_AND_FREE(loaderList->initiatingLoaders); 2078 2079 clazz->interfaceCount = -1; 2080 NULL_AND_LINEAR_FREE(clazz->interfaces); 2081 2082 clazz->iftableCount = -1; 2083 NULL_AND_LINEAR_FREE(clazz->iftable); 2084 2085 clazz->ifviPoolCount = -1; 2086 NULL_AND_LINEAR_FREE(clazz->ifviPool); 2087 2088 clazz->sfieldCount = -1; 2089 /* The sfields are attached to the ClassObject, and will be freed 2090 * with it. */ 2091 2092 clazz->ifieldCount = -1; 2093 NULL_AND_LINEAR_FREE(clazz->ifields); 2094 2095 #undef NULL_AND_FREE 2096 #undef NULL_AND_LINEAR_FREE 2097 } 2098 2099 /* 2100 * Free anything in a Method that was allocated on the system heap. 2101 * 2102 * The containing class is largely torn down by this point. 2103 */ 2104 static void freeMethodInnards(Method* meth) 2105 { 2106 #if 0 2107 free(meth->exceptions); 2108 free(meth->lines); 2109 free(meth->locals); 2110 #endif 2111 2112 /* 2113 * Some register maps are allocated on the heap, either because of late 2114 * verification or because we're caching an uncompressed form. 2115 */ 2116 const RegisterMap* pMap = meth->registerMap; 2117 if (pMap != NULL && dvmRegisterMapGetOnHeap(pMap)) { 2118 dvmFreeRegisterMap((RegisterMap*) pMap); 2119 meth->registerMap = NULL; 2120 } 2121 2122 /* 2123 * We may have copied the instructions. 2124 */ 2125 if (IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) { 2126 DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth); 2127 dvmLinearFree(meth->clazz->classLoader, methodDexCode); 2128 } 2129 } 2130 2131 /* 2132 * Clone a Method, making new copies of anything that will be freed up 2133 * by freeMethodInnards(). This is used for "miranda" methods. 2134 */ 2135 static void cloneMethod(Method* dst, const Method* src) 2136 { 2137 if (src->registerMap != NULL) { 2138 ALOGE("GLITCH: only expected abstract methods here"); 2139 ALOGE(" cloning %s.%s", src->clazz->descriptor, src->name); 2140 dvmAbort(); 2141 } 2142 memcpy(dst, src, sizeof(Method)); 2143 } 2144 2145 /* 2146 * Pull the interesting pieces out of a DexMethod. 2147 * 2148 * The DEX file isn't going anywhere, so we don't need to make copies of 2149 * the code area. 2150 */ 2151 static void loadMethodFromDex(ClassObject* clazz, const DexMethod* pDexMethod, 2152 Method* meth) 2153 { 2154 DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2155 const DexMethodId* pMethodId; 2156 const DexCode* pDexCode; 2157 2158 pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx); 2159 2160 meth->name = dexStringById(pDexFile, pMethodId->nameIdx); 2161 dexProtoSetFromMethodId(&meth->prototype, pDexFile, pMethodId); 2162 meth->shorty = dexProtoGetShorty(&meth->prototype); 2163 meth->accessFlags = pDexMethod->accessFlags; 2164 meth->clazz = clazz; 2165 meth->jniArgInfo = 0; 2166 2167 if (dvmCompareNameDescriptorAndMethod("finalize", "()V", meth) == 0) { 2168 /* 2169 * The Enum class declares a "final" finalize() method to 2170 * prevent subclasses from introducing a finalizer. We don't 2171 * want to set the finalizable flag for Enum or its subclasses, 2172 * so we check for it here. 2173 * 2174 * We also want to avoid setting it on Object, but it's easier 2175 * to just strip that out later. 2176 */ 2177 if (clazz->classLoader != NULL || 2178 strcmp(clazz->descriptor, "Ljava/lang/Enum;") != 0) 2179 { 2180 SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE); 2181 } 2182 } 2183 2184 pDexCode = dexGetCode(pDexFile, pDexMethod); 2185 if (pDexCode != NULL) { 2186 /* integer constants, copy over for faster access */ 2187 meth->registersSize = pDexCode->registersSize; 2188 meth->insSize = pDexCode->insSize; 2189 meth->outsSize = pDexCode->outsSize; 2190 2191 /* pointer to code area */ 2192 meth->insns = pDexCode->insns; 2193 } else { 2194 /* 2195 * We don't have a DexCode block, but we still want to know how 2196 * much space is needed for the arguments (so we don't have to 2197 * compute it later). We also take this opportunity to compute 2198 * JNI argument info. 2199 * 2200 * We do this for abstract methods as well, because we want to 2201 * be able to substitute our exception-throwing "stub" in. 2202 */ 2203 int argsSize = dvmComputeMethodArgsSize(meth); 2204 if (!dvmIsStaticMethod(meth)) 2205 argsSize++; 2206 meth->registersSize = meth->insSize = argsSize; 2207 assert(meth->outsSize == 0); 2208 assert(meth->insns == NULL); 2209 2210 if (dvmIsNativeMethod(meth)) { 2211 meth->nativeFunc = dvmResolveNativeMethod; 2212 meth->jniArgInfo = computeJniArgInfo(&meth->prototype); 2213 } 2214 } 2215 } 2216 2217 #if 0 /* replaced with private/read-write mapping */ 2218 /* 2219 * We usually map bytecode directly out of the DEX file, which is mapped 2220 * shared read-only. If we want to be able to modify it, we have to make 2221 * a new copy. 2222 * 2223 * Once copied, the code will be in the LinearAlloc region, which may be 2224 * marked read-only. 2225 * 2226 * The bytecode instructions are embedded inside a DexCode structure, so we 2227 * need to copy all of that. (The dvmGetMethodCode function backs up the 2228 * instruction pointer to find the start of the DexCode.) 2229 */ 2230 void dvmMakeCodeReadWrite(Method* meth) 2231 { 2232 DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth); 2233 2234 if (IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) { 2235 dvmLinearReadWrite(meth->clazz->classLoader, methodDexCode); 2236 return; 2237 } 2238 2239 assert(!dvmIsNativeMethod(meth) && !dvmIsAbstractMethod(meth)); 2240 2241 size_t dexCodeSize = dexGetDexCodeSize(methodDexCode); 2242 ALOGD("Making a copy of %s.%s code (%d bytes)", 2243 meth->clazz->descriptor, meth->name, dexCodeSize); 2244 2245 DexCode* newCode = 2246 (DexCode*) dvmLinearAlloc(meth->clazz->classLoader, dexCodeSize); 2247 memcpy(newCode, methodDexCode, dexCodeSize); 2248 2249 meth->insns = newCode->insns; 2250 SET_METHOD_FLAG(meth, METHOD_ISWRITABLE); 2251 } 2252 2253 /* 2254 * Mark the bytecode read-only. 2255 * 2256 * If the contents of the DexCode haven't actually changed, we could revert 2257 * to the original shared page. 2258 */ 2259 void dvmMakeCodeReadOnly(Method* meth) 2260 { 2261 DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth); 2262 ALOGV("+++ marking %p read-only", methodDexCode); 2263 dvmLinearReadOnly(meth->clazz->classLoader, methodDexCode); 2264 } 2265 #endif 2266 2267 2268 /* 2269 * jniArgInfo (32-bit int) layout: 2270 * SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH 2271 * 2272 * S - if set, do things the hard way (scan the signature) 2273 * R - return-type enumeration 2274 * H - target-specific hints 2275 * 2276 * This info is used at invocation time by dvmPlatformInvoke. In most 2277 * cases, the target-specific hints allow dvmPlatformInvoke to avoid 2278 * having to fully parse the signature. 2279 * 2280 * The return-type bits are always set, even if target-specific hint bits 2281 * are unavailable. 2282 */ 2283 static int computeJniArgInfo(const DexProto* proto) 2284 { 2285 const char* sig = dexProtoGetShorty(proto); 2286 int returnType, jniArgInfo; 2287 u4 hints; 2288 2289 /* The first shorty character is the return type. */ 2290 switch (*(sig++)) { 2291 case 'V': 2292 returnType = DALVIK_JNI_RETURN_VOID; 2293 break; 2294 case 'F': 2295 returnType = DALVIK_JNI_RETURN_FLOAT; 2296 break; 2297 case 'D': 2298 returnType = DALVIK_JNI_RETURN_DOUBLE; 2299 break; 2300 case 'J': 2301 returnType = DALVIK_JNI_RETURN_S8; 2302 break; 2303 case 'Z': 2304 case 'B': 2305 returnType = DALVIK_JNI_RETURN_S1; 2306 break; 2307 case 'C': 2308 returnType = DALVIK_JNI_RETURN_U2; 2309 break; 2310 case 'S': 2311 returnType = DALVIK_JNI_RETURN_S2; 2312 break; 2313 default: 2314 returnType = DALVIK_JNI_RETURN_S4; 2315 break; 2316 } 2317 2318 jniArgInfo = returnType << DALVIK_JNI_RETURN_SHIFT; 2319 2320 hints = dvmPlatformInvokeHints(proto); 2321 2322 if (hints & DALVIK_JNI_NO_ARG_INFO) { 2323 jniArgInfo |= DALVIK_JNI_NO_ARG_INFO; 2324 } else { 2325 assert((hints & DALVIK_JNI_RETURN_MASK) == 0); 2326 jniArgInfo |= hints; 2327 } 2328 2329 return jniArgInfo; 2330 } 2331 2332 /* 2333 * Load information about a static field. 2334 * 2335 * This also "prepares" static fields by initializing them 2336 * to their "standard default values". 2337 */ 2338 static void loadSFieldFromDex(ClassObject* clazz, 2339 const DexField* pDexSField, StaticField* sfield) 2340 { 2341 DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2342 const DexFieldId* pFieldId; 2343 2344 pFieldId = dexGetFieldId(pDexFile, pDexSField->fieldIdx); 2345 2346 sfield->clazz = clazz; 2347 sfield->name = dexStringById(pDexFile, pFieldId->nameIdx); 2348 sfield->signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx); 2349 sfield->accessFlags = pDexSField->accessFlags; 2350 2351 /* Static object field values are set to "standard default values" 2352 * (null or 0) until the class is initialized. We delay loading 2353 * constant values from the class until that time. 2354 */ 2355 //sfield->value.j = 0; 2356 assert(sfield->value.j == 0LL); // cleared earlier with calloc 2357 } 2358 2359 /* 2360 * Load information about an instance field. 2361 */ 2362 static void loadIFieldFromDex(ClassObject* clazz, 2363 const DexField* pDexIField, InstField* ifield) 2364 { 2365 DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2366 const DexFieldId* pFieldId; 2367 2368 pFieldId = dexGetFieldId(pDexFile, pDexIField->fieldIdx); 2369 2370 ifield->clazz = clazz; 2371 ifield->name = dexStringById(pDexFile, pFieldId->nameIdx); 2372 ifield->signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx); 2373 ifield->accessFlags = pDexIField->accessFlags; 2374 #ifndef NDEBUG 2375 assert(ifield->byteOffset == 0); // cleared earlier with calloc 2376 ifield->byteOffset = -1; // make it obvious if we fail to set later 2377 #endif 2378 } 2379 2380 /* 2381 * Cache java.lang.ref.Reference fields and methods. 2382 */ 2383 static bool precacheReferenceOffsets(ClassObject* clazz) 2384 { 2385 int i; 2386 2387 /* We trick the GC object scanner by not counting 2388 * java.lang.ref.Reference.referent as an object 2389 * field. It will get explicitly scanned as part 2390 * of the reference-walking process. 2391 * 2392 * Find the object field named "referent" and put it 2393 * just after the list of object reference fields. 2394 */ 2395 dvmLinearReadWrite(clazz->classLoader, clazz->ifields); 2396 for (i = 0; i < clazz->ifieldRefCount; i++) { 2397 InstField *pField = &clazz->ifields[i]; 2398 if (strcmp(pField->name, "referent") == 0) { 2399 int targetIndex; 2400 2401 /* Swap this field with the last object field. 2402 */ 2403 targetIndex = clazz->ifieldRefCount - 1; 2404 if (i != targetIndex) { 2405 InstField *swapField = &clazz->ifields[targetIndex]; 2406 InstField tmpField; 2407 int tmpByteOffset; 2408 2409 /* It's not currently strictly necessary 2410 * for the fields to be in byteOffset order, 2411 * but it's more predictable that way. 2412 */ 2413 tmpByteOffset = swapField->byteOffset; 2414 swapField->byteOffset = pField->byteOffset; 2415 pField->byteOffset = tmpByteOffset; 2416 2417 tmpField = *swapField; 2418 *swapField = *pField; 2419 *pField = tmpField; 2420 } 2421 2422 /* One fewer object field (wink wink). 2423 */ 2424 clazz->ifieldRefCount--; 2425 i--; /* don't trip "didn't find it" test if field was last */ 2426 break; 2427 } 2428 } 2429 dvmLinearReadOnly(clazz->classLoader, clazz->ifields); 2430 if (i == clazz->ifieldRefCount) { 2431 ALOGE("Unable to reorder 'referent' in %s", clazz->descriptor); 2432 return false; 2433 } 2434 2435 /* 2436 * Now that the above has been done, it is safe to cache 2437 * info about the class. 2438 */ 2439 if (!dvmFindReferenceMembers(clazz)) { 2440 ALOGE("Trouble with Reference setup"); 2441 return false; 2442 } 2443 2444 return true; 2445 } 2446 2447 2448 /* 2449 * Set the bitmap of reference offsets, refOffsets, from the ifields 2450 * list. 2451 */ 2452 static void computeRefOffsets(ClassObject* clazz) 2453 { 2454 if (clazz->super != NULL) { 2455 clazz->refOffsets = clazz->super->refOffsets; 2456 } else { 2457 clazz->refOffsets = 0; 2458 } 2459 /* 2460 * If our superclass overflowed, we don't stand a chance. 2461 */ 2462 if (clazz->refOffsets != CLASS_WALK_SUPER) { 2463 InstField *f; 2464 int i; 2465 2466 /* All of the fields that contain object references 2467 * are guaranteed to be at the beginning of the ifields list. 2468 */ 2469 f = clazz->ifields; 2470 const int ifieldRefCount = clazz->ifieldRefCount; 2471 for (i = 0; i < ifieldRefCount; i++) { 2472 /* 2473 * Note that, per the comment on struct InstField, 2474 * f->byteOffset is the offset from the beginning of 2475 * obj, not the offset into obj->instanceData. 2476 */ 2477 assert(f->byteOffset >= (int) CLASS_SMALLEST_OFFSET); 2478 assert((f->byteOffset & (CLASS_OFFSET_ALIGNMENT - 1)) == 0); 2479 if (CLASS_CAN_ENCODE_OFFSET(f->byteOffset)) { 2480 u4 newBit = CLASS_BIT_FROM_OFFSET(f->byteOffset); 2481 assert(newBit != 0); 2482 clazz->refOffsets |= newBit; 2483 } else { 2484 clazz->refOffsets = CLASS_WALK_SUPER; 2485 break; 2486 } 2487 f++; 2488 } 2489 } 2490 } 2491 2492 2493 /* 2494 * Link (prepare and resolve). Verification is deferred until later. 2495 * 2496 * This converts symbolic references into pointers. It's independent of 2497 * the source file format. 2498 * 2499 * If clazz->status is CLASS_IDX, then clazz->super and interfaces[] are 2500 * holding class reference indices rather than pointers. The class 2501 * references will be resolved during link. (This is done when 2502 * loading from DEX to avoid having to create additional storage to 2503 * pass the indices around.) 2504 * 2505 * Returns "false" with an exception pending on failure. 2506 */ 2507 bool dvmLinkClass(ClassObject* clazz) 2508 { 2509 u4 superclassIdx = 0; 2510 u4 *interfaceIdxArray = NULL; 2511 bool okay = false; 2512 int i; 2513 2514 assert(clazz != NULL); 2515 assert(clazz->descriptor != NULL); 2516 assert(clazz->status == CLASS_IDX || clazz->status == CLASS_LOADED); 2517 if (gDvm.verboseClass) 2518 ALOGV("CLASS: linking '%s'...", clazz->descriptor); 2519 2520 assert(gDvm.classJavaLangClass != NULL); 2521 assert(clazz->clazz == gDvm.classJavaLangClass); 2522 assert(dvmIsClassObject(clazz)); 2523 if (clazz->classLoader == NULL && 2524 (strcmp(clazz->descriptor, "Ljava/lang/Class;") == 0)) 2525 { 2526 if (gDvm.classJavaLangClass->ifieldCount > CLASS_FIELD_SLOTS) { 2527 ALOGE("java.lang.Class has %d instance fields (expected at most %d)", 2528 gDvm.classJavaLangClass->ifieldCount, CLASS_FIELD_SLOTS); 2529 dvmAbort(); 2530 } 2531 if (gDvm.classJavaLangClass->sfieldCount != CLASS_SFIELD_SLOTS) { 2532 ALOGE("java.lang.Class has %d static fields (expected %d)", 2533 gDvm.classJavaLangClass->sfieldCount, CLASS_SFIELD_SLOTS); 2534 dvmAbort(); 2535 } 2536 } 2537 2538 /* "Resolve" the class. 2539 * 2540 * At this point, clazz's reference fields may contain Dex file 2541 * indices instead of direct object references. Proxy objects are 2542 * an exception, and may be the only exception. We need to 2543 * translate those indices into real references, and let the GC 2544 * look inside this ClassObject. 2545 */ 2546 if (clazz->status == CLASS_IDX) { 2547 if (clazz->interfaceCount > 0) { 2548 /* Copy u4 DEX idx values out of the ClassObject* array 2549 * where we stashed them. 2550 */ 2551 assert(sizeof(*interfaceIdxArray) == sizeof(*clazz->interfaces)); 2552 size_t len = clazz->interfaceCount * sizeof(*interfaceIdxArray); 2553 interfaceIdxArray = (u4*)malloc(len); 2554 if (interfaceIdxArray == NULL) { 2555 ALOGW("Unable to allocate memory to link %s", clazz->descriptor); 2556 goto bail; 2557 } 2558 memcpy(interfaceIdxArray, clazz->interfaces, len); 2559 2560 dvmLinearReadWrite(clazz->classLoader, clazz->interfaces); 2561 memset(clazz->interfaces, 0, len); 2562 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2563 } 2564 2565 assert(sizeof(superclassIdx) == sizeof(clazz->super)); 2566 superclassIdx = (u4) clazz->super; 2567 clazz->super = NULL; 2568 /* After this line, clazz will be fair game for the GC. The 2569 * superclass and interfaces are all NULL. 2570 */ 2571 clazz->status = CLASS_LOADED; 2572 2573 if (superclassIdx != kDexNoIndex) { 2574 ClassObject* super = dvmResolveClass(clazz, superclassIdx, false); 2575 if (super == NULL) { 2576 assert(dvmCheckException(dvmThreadSelf())); 2577 if (gDvm.optimizing) { 2578 /* happens with "external" libs */ 2579 ALOGV("Unable to resolve superclass of %s (%d)", 2580 clazz->descriptor, superclassIdx); 2581 } else { 2582 ALOGW("Unable to resolve superclass of %s (%d)", 2583 clazz->descriptor, superclassIdx); 2584 } 2585 goto bail; 2586 } 2587 dvmSetFieldObject((Object *)clazz, 2588 OFFSETOF_MEMBER(ClassObject, super), 2589 (Object *)super); 2590 } 2591 2592 if (clazz->interfaceCount > 0) { 2593 /* Resolve the interfaces implemented directly by this class. */ 2594 assert(interfaceIdxArray != NULL); 2595 dvmLinearReadWrite(clazz->classLoader, clazz->interfaces); 2596 for (i = 0; i < clazz->interfaceCount; i++) { 2597 assert(interfaceIdxArray[i] != kDexNoIndex); 2598 clazz->interfaces[i] = 2599 dvmResolveClass(clazz, interfaceIdxArray[i], false); 2600 if (clazz->interfaces[i] == NULL) { 2601 const DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2602 2603 assert(dvmCheckException(dvmThreadSelf())); 2604 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2605 2606 const char* classDescriptor; 2607 classDescriptor = 2608 dexStringByTypeIdx(pDexFile, interfaceIdxArray[i]); 2609 if (gDvm.optimizing) { 2610 /* happens with "external" libs */ 2611 ALOGV("Failed resolving %s interface %d '%s'", 2612 clazz->descriptor, interfaceIdxArray[i], 2613 classDescriptor); 2614 } else { 2615 ALOGI("Failed resolving %s interface %d '%s'", 2616 clazz->descriptor, interfaceIdxArray[i], 2617 classDescriptor); 2618 } 2619 goto bail; 2620 } 2621 2622 /* are we allowed to implement this interface? */ 2623 if (!dvmCheckClassAccess(clazz, clazz->interfaces[i])) { 2624 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2625 ALOGW("Interface '%s' is not accessible to '%s'", 2626 clazz->interfaces[i]->descriptor, clazz->descriptor); 2627 dvmThrowIllegalAccessError("interface not accessible"); 2628 goto bail; 2629 } 2630 LOGVV("+++ found interface '%s'", 2631 clazz->interfaces[i]->descriptor); 2632 } 2633 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2634 } 2635 } 2636 /* 2637 * There are now Class references visible to the GC in super and 2638 * interfaces. 2639 */ 2640 2641 /* 2642 * All classes have a direct superclass, except for 2643 * java/lang/Object and primitive classes. Primitive classes are 2644 * are created CLASS_INITIALIZED, so won't get here. 2645 */ 2646 assert(clazz->primitiveType == PRIM_NOT); 2647 if (strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0) { 2648 if (clazz->super != NULL) { 2649 /* TODO: is this invariant true for all java/lang/Objects, 2650 * regardless of the class loader? For now, assume it is. 2651 */ 2652 dvmThrowClassFormatError("java.lang.Object has a superclass"); 2653 goto bail; 2654 } 2655 2656 /* Don't finalize objects whose classes use the 2657 * default (empty) Object.finalize(). 2658 */ 2659 CLEAR_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE); 2660 } else { 2661 if (clazz->super == NULL) { 2662 dvmThrowLinkageError("no superclass defined"); 2663 goto bail; 2664 } 2665 /* verify */ 2666 if (dvmIsFinalClass(clazz->super)) { 2667 ALOGW("Superclass of '%s' is final '%s'", 2668 clazz->descriptor, clazz->super->descriptor); 2669 dvmThrowIncompatibleClassChangeError("superclass is final"); 2670 goto bail; 2671 } else if (dvmIsInterfaceClass(clazz->super)) { 2672 ALOGW("Superclass of '%s' is interface '%s'", 2673 clazz->descriptor, clazz->super->descriptor); 2674 dvmThrowIncompatibleClassChangeError("superclass is an interface"); 2675 goto bail; 2676 } else if (!dvmCheckClassAccess(clazz, clazz->super)) { 2677 ALOGW("Superclass of '%s' (%s) is not accessible", 2678 clazz->descriptor, clazz->super->descriptor); 2679 dvmThrowIllegalAccessError("superclass not accessible"); 2680 goto bail; 2681 } 2682 2683 /* Inherit finalizability from the superclass. If this 2684 * class also overrides finalize(), its CLASS_ISFINALIZABLE 2685 * bit will already be set. 2686 */ 2687 if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISFINALIZABLE)) { 2688 SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE); 2689 } 2690 2691 /* See if this class descends from java.lang.Reference 2692 * and set the class flags appropriately. 2693 */ 2694 if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISREFERENCE)) { 2695 u4 superRefFlags; 2696 2697 /* We've already determined the reference type of this 2698 * inheritance chain. Inherit reference-ness from the superclass. 2699 */ 2700 superRefFlags = GET_CLASS_FLAG_GROUP(clazz->super, 2701 CLASS_ISREFERENCE | 2702 CLASS_ISWEAKREFERENCE | 2703 CLASS_ISFINALIZERREFERENCE | 2704 CLASS_ISPHANTOMREFERENCE); 2705 SET_CLASS_FLAG(clazz, superRefFlags); 2706 } else if (clazz->classLoader == NULL && 2707 clazz->super->classLoader == NULL && 2708 strcmp(clazz->super->descriptor, 2709 "Ljava/lang/ref/Reference;") == 0) 2710 { 2711 u4 refFlags; 2712 2713 /* This class extends Reference, which means it should 2714 * be one of the magic Soft/Weak/PhantomReference classes. 2715 */ 2716 refFlags = CLASS_ISREFERENCE; 2717 if (strcmp(clazz->descriptor, 2718 "Ljava/lang/ref/SoftReference;") == 0) 2719 { 2720 /* Only CLASS_ISREFERENCE is set for soft references. 2721 */ 2722 } else if (strcmp(clazz->descriptor, 2723 "Ljava/lang/ref/WeakReference;") == 0) 2724 { 2725 refFlags |= CLASS_ISWEAKREFERENCE; 2726 } else if (strcmp(clazz->descriptor, 2727 "Ljava/lang/ref/FinalizerReference;") == 0) 2728 { 2729 refFlags |= CLASS_ISFINALIZERREFERENCE; 2730 } else if (strcmp(clazz->descriptor, 2731 "Ljava/lang/ref/PhantomReference;") == 0) 2732 { 2733 refFlags |= CLASS_ISPHANTOMREFERENCE; 2734 } else { 2735 /* No-one else is allowed to inherit directly 2736 * from Reference. 2737 */ 2738 //xxx is this the right exception? better than an assertion. 2739 dvmThrowLinkageError("illegal inheritance from Reference"); 2740 goto bail; 2741 } 2742 2743 /* The class should not have any reference bits set yet. 2744 */ 2745 assert(GET_CLASS_FLAG_GROUP(clazz, 2746 CLASS_ISREFERENCE | 2747 CLASS_ISWEAKREFERENCE | 2748 CLASS_ISFINALIZERREFERENCE | 2749 CLASS_ISPHANTOMREFERENCE) == 0); 2750 2751 SET_CLASS_FLAG(clazz, refFlags); 2752 } 2753 } 2754 2755 /* 2756 * Populate vtable. 2757 */ 2758 if (dvmIsInterfaceClass(clazz)) { 2759 /* no vtable; just set the method indices */ 2760 int count = clazz->virtualMethodCount; 2761 2762 if (count != (u2) count) { 2763 ALOGE("Too many methods (%d) in interface '%s'", count, 2764 clazz->descriptor); 2765 goto bail; 2766 } 2767 2768 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 2769 2770 for (i = 0; i < count; i++) 2771 clazz->virtualMethods[i].methodIndex = (u2) i; 2772 2773 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 2774 } else { 2775 if (!createVtable(clazz)) { 2776 ALOGW("failed creating vtable"); 2777 goto bail; 2778 } 2779 } 2780 2781 /* 2782 * Populate interface method tables. Can alter the vtable. 2783 */ 2784 if (!createIftable(clazz)) 2785 goto bail; 2786 2787 /* 2788 * Insert special-purpose "stub" method implementations. 2789 */ 2790 if (!insertMethodStubs(clazz)) 2791 goto bail; 2792 2793 /* 2794 * Compute instance field offsets and, hence, the size of the object. 2795 */ 2796 if (!computeFieldOffsets(clazz)) 2797 goto bail; 2798 2799 /* 2800 * Cache field and method info for the class Reference (as loaded 2801 * by the boot classloader). This has to happen after the call to 2802 * computeFieldOffsets(). 2803 */ 2804 if ((clazz->classLoader == NULL) 2805 && (strcmp(clazz->descriptor, "Ljava/lang/ref/Reference;") == 0)) { 2806 if (!precacheReferenceOffsets(clazz)) { 2807 ALOGE("failed pre-caching Reference offsets"); 2808 dvmThrowInternalError(NULL); 2809 goto bail; 2810 } 2811 } 2812 2813 /* 2814 * Compact the offsets the GC has to examine into a bitmap, if 2815 * possible. (This has to happen after Reference.referent is 2816 * massaged in precacheReferenceOffsets.) 2817 */ 2818 computeRefOffsets(clazz); 2819 2820 /* 2821 * Done! 2822 */ 2823 if (IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED)) 2824 clazz->status = CLASS_VERIFIED; 2825 else 2826 clazz->status = CLASS_RESOLVED; 2827 okay = true; 2828 if (gDvm.verboseClass) 2829 ALOGV("CLASS: linked '%s'", clazz->descriptor); 2830 2831 /* 2832 * We send CLASS_PREPARE events to the debugger from here. The 2833 * definition of "preparation" is creating the static fields for a 2834 * class and initializing them to the standard default values, but not 2835 * executing any code (that comes later, during "initialization"). 2836 * 2837 * We did the static prep in loadSFieldFromDex() while loading the class. 2838 * 2839 * The class has been prepared and resolved but possibly not yet verified 2840 * at this point. 2841 */ 2842 if (gDvm.debuggerActive) { 2843 dvmDbgPostClassPrepare(clazz); 2844 } 2845 2846 bail: 2847 if (!okay) { 2848 clazz->status = CLASS_ERROR; 2849 if (!dvmCheckException(dvmThreadSelf())) { 2850 dvmThrowVirtualMachineError(NULL); 2851 } 2852 } 2853 if (interfaceIdxArray != NULL) { 2854 free(interfaceIdxArray); 2855 } 2856 2857 return okay; 2858 } 2859 2860 /* 2861 * Create the virtual method table. 2862 * 2863 * The top part of the table is a copy of the table from our superclass, 2864 * with our local methods overriding theirs. The bottom part of the table 2865 * has any new methods we defined. 2866 */ 2867 static bool createVtable(ClassObject* clazz) 2868 { 2869 bool result = false; 2870 int maxCount; 2871 int i; 2872 2873 if (clazz->super != NULL) { 2874 //ALOGI("SUPER METHODS %d %s->%s", clazz->super->vtableCount, 2875 // clazz->descriptor, clazz->super->descriptor); 2876 } 2877 2878 /* the virtual methods we define, plus the superclass vtable size */ 2879 maxCount = clazz->virtualMethodCount; 2880 if (clazz->super != NULL) { 2881 maxCount += clazz->super->vtableCount; 2882 } else { 2883 /* TODO: is this invariant true for all java/lang/Objects, 2884 * regardless of the class loader? For now, assume it is. 2885 */ 2886 assert(strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0); 2887 } 2888 //ALOGD("+++ max vmethods for '%s' is %d", clazz->descriptor, maxCount); 2889 2890 /* 2891 * Over-allocate the table, then realloc it down if necessary. So 2892 * long as we don't allocate anything in between we won't cause 2893 * fragmentation, and reducing the size should be unlikely to cause 2894 * a buffer copy. 2895 */ 2896 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 2897 clazz->vtable = (Method**) dvmLinearAlloc(clazz->classLoader, 2898 sizeof(Method*) * maxCount); 2899 if (clazz->vtable == NULL) 2900 goto bail; 2901 2902 if (clazz->super != NULL) { 2903 int actualCount; 2904 2905 memcpy(clazz->vtable, clazz->super->vtable, 2906 sizeof(*(clazz->vtable)) * clazz->super->vtableCount); 2907 actualCount = clazz->super->vtableCount; 2908 2909 /* 2910 * See if any of our virtual methods override the superclass. 2911 */ 2912 for (i = 0; i < clazz->virtualMethodCount; i++) { 2913 Method* localMeth = &clazz->virtualMethods[i]; 2914 int si; 2915 2916 for (si = 0; si < clazz->super->vtableCount; si++) { 2917 Method* superMeth = clazz->vtable[si]; 2918 2919 if (dvmCompareMethodNamesAndProtos(localMeth, superMeth) == 0) { 2920 // We should have an access check here, but some apps rely on us not 2921 // checking access: http://b/7301030 2922 bool isAccessible = dvmCheckMethodAccess(clazz, superMeth); 2923 if (dvmIsFinalMethod(superMeth)) { 2924 ALOGE("Method %s.%s overrides final %s.%s", 2925 localMeth->clazz->descriptor, localMeth->name, 2926 superMeth->clazz->descriptor, superMeth->name); 2927 goto bail; 2928 } 2929 2930 // Warn if we just spotted code relying on this bug... 2931 if (!isAccessible) { 2932 ALOGW("method %s.%s incorrectly overrides " 2933 "package-private method with same name in %s", 2934 localMeth->clazz->descriptor, localMeth->name, 2935 superMeth->clazz->descriptor); 2936 } 2937 2938 clazz->vtable[si] = localMeth; 2939 localMeth->methodIndex = (u2) si; 2940 //ALOGV("+++ override %s.%s (slot %d)", 2941 // clazz->descriptor, localMeth->name, si); 2942 break; 2943 } 2944 } 2945 2946 if (si == clazz->super->vtableCount) { 2947 /* not an override, add to end */ 2948 clazz->vtable[actualCount] = localMeth; 2949 localMeth->methodIndex = (u2) actualCount; 2950 actualCount++; 2951 2952 //ALOGV("+++ add method %s.%s", 2953 // clazz->descriptor, localMeth->name); 2954 } 2955 } 2956 2957 if (actualCount != (u2) actualCount) { 2958 ALOGE("Too many methods (%d) in class '%s'", actualCount, 2959 clazz->descriptor); 2960 goto bail; 2961 } 2962 2963 assert(actualCount <= maxCount); 2964 2965 if (actualCount < maxCount) { 2966 assert(clazz->vtable != NULL); 2967 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 2968 clazz->vtable = (Method **)dvmLinearRealloc(clazz->classLoader, 2969 clazz->vtable, sizeof(*(clazz->vtable)) * actualCount); 2970 if (clazz->vtable == NULL) { 2971 ALOGE("vtable realloc failed"); 2972 goto bail; 2973 } else { 2974 LOGVV("+++ reduced vtable from %d to %d", 2975 maxCount, actualCount); 2976 } 2977 } 2978 2979 clazz->vtableCount = actualCount; 2980 } else { 2981 /* java/lang/Object case */ 2982 int count = clazz->virtualMethodCount; 2983 if (count != (u2) count) { 2984 ALOGE("Too many methods (%d) in base class '%s'", count, 2985 clazz->descriptor); 2986 goto bail; 2987 } 2988 2989 for (i = 0; i < count; i++) { 2990 clazz->vtable[i] = &clazz->virtualMethods[i]; 2991 clazz->virtualMethods[i].methodIndex = (u2) i; 2992 } 2993 clazz->vtableCount = clazz->virtualMethodCount; 2994 } 2995 2996 result = true; 2997 2998 bail: 2999 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 3000 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3001 return result; 3002 } 3003 3004 /* 3005 * Create and populate "iftable". 3006 * 3007 * The set of interfaces we support is the combination of the interfaces 3008 * we implement directly and those implemented by our superclass. Each 3009 * interface can have one or more "superinterfaces", which we must also 3010 * support. For speed we flatten the tree out. 3011 * 3012 * We might be able to speed this up when there are lots of interfaces 3013 * by merge-sorting the class pointers and binary-searching when removing 3014 * duplicates. We could also drop the duplicate removal -- it's only 3015 * there to reduce the memory footprint. 3016 * 3017 * Because of "Miranda methods", this may reallocate clazz->virtualMethods. 3018 * 3019 * Returns "true" on success. 3020 */ 3021 static bool createIftable(ClassObject* clazz) 3022 { 3023 bool result = false; 3024 bool zapIftable = false; 3025 bool zapVtable = false; 3026 bool zapIfvipool = false; 3027 int poolOffset = 0, poolSize = 0; 3028 Method** mirandaList = NULL; 3029 int mirandaCount = 0, mirandaAlloc = 0; 3030 3031 int superIfCount; 3032 if (clazz->super != NULL) 3033 superIfCount = clazz->super->iftableCount; 3034 else 3035 superIfCount = 0; 3036 3037 int ifCount = superIfCount; 3038 ifCount += clazz->interfaceCount; 3039 for (int i = 0; i < clazz->interfaceCount; i++) 3040 ifCount += clazz->interfaces[i]->iftableCount; 3041 3042 LOGVV("INTF: class '%s' direct w/supra=%d super=%d total=%d", 3043 clazz->descriptor, ifCount - superIfCount, superIfCount, ifCount); 3044 3045 if (ifCount == 0) { 3046 assert(clazz->iftableCount == 0); 3047 assert(clazz->iftable == NULL); 3048 return true; 3049 } 3050 3051 /* 3052 * Create a table with enough space for all interfaces, and copy the 3053 * superclass' table in. 3054 */ 3055 clazz->iftable = (InterfaceEntry*) dvmLinearAlloc(clazz->classLoader, 3056 sizeof(InterfaceEntry) * ifCount); 3057 zapIftable = true; 3058 memset(clazz->iftable, 0x00, sizeof(InterfaceEntry) * ifCount); 3059 if (superIfCount != 0) { 3060 memcpy(clazz->iftable, clazz->super->iftable, 3061 sizeof(InterfaceEntry) * superIfCount); 3062 } 3063 3064 /* 3065 * Create a flattened interface hierarchy of our immediate interfaces. 3066 */ 3067 int idx = superIfCount; 3068 3069 for (int i = 0; i < clazz->interfaceCount; i++) { 3070 ClassObject* interf = clazz->interfaces[i]; 3071 assert(interf != NULL); 3072 3073 /* make sure this is still an interface class */ 3074 if (!dvmIsInterfaceClass(interf)) { 3075 ALOGW("Class '%s' implements non-interface '%s'", 3076 clazz->descriptor, interf->descriptor); 3077 dvmThrowIncompatibleClassChangeErrorWithClassMessage( 3078 clazz->descriptor); 3079 goto bail; 3080 } 3081 3082 /* add entry for this interface */ 3083 clazz->iftable[idx++].clazz = interf; 3084 3085 /* add entries for the interface's superinterfaces */ 3086 for (int j = 0; j < interf->iftableCount; j++) { 3087 int k; 3088 ClassObject *cand; 3089 3090 cand = interf->iftable[j].clazz; 3091 3092 /* 3093 * Check if this interface was already added and add only if new. 3094 * This is to avoid a potential blowup in the number of 3095 * interfaces for sufficiently complicated interface hierarchies. 3096 * This has quadratic runtime in the number of interfaces. 3097 * However, in common cases with little interface inheritance, this 3098 * doesn't make much of a difference. 3099 */ 3100 for (k = 0; k < idx; k++) 3101 if (clazz->iftable[k].clazz == cand) 3102 break; 3103 3104 if (k == idx) 3105 clazz->iftable[idx++].clazz = cand; 3106 } 3107 } 3108 3109 assert(idx <= ifCount); 3110 3111 /* 3112 * Adjust the ifCount. We could reallocate the interface memory here, 3113 * but it's probably not worth the effort, the important thing here 3114 * is to avoid the interface blowup and keep the ifCount low. 3115 */ 3116 if (false) { 3117 if (idx != ifCount) { 3118 int newIfCount = idx; 3119 InterfaceEntry* oldmem = clazz->iftable; 3120 3121 clazz->iftable = (InterfaceEntry*) dvmLinearAlloc(clazz->classLoader, 3122 sizeof(InterfaceEntry) * newIfCount); 3123 memcpy(clazz->iftable, oldmem, sizeof(InterfaceEntry) * newIfCount); 3124 dvmLinearFree(clazz->classLoader, oldmem); 3125 } 3126 } 3127 3128 ifCount = idx; 3129 clazz->iftableCount = ifCount; 3130 3131 /* 3132 * If we're an interface, we don't need the vtable pointers, so 3133 * we're done. If this class doesn't implement an interface that our 3134 * superclass doesn't have, then we again have nothing to do. 3135 */ 3136 if (dvmIsInterfaceClass(clazz) || superIfCount == ifCount) { 3137 //dvmDumpClass(clazz, kDumpClassFullDetail); 3138 result = true; 3139 goto bail; 3140 } 3141 3142 /* 3143 * When we're handling invokeinterface, we probably have an object 3144 * whose type is an interface class rather than a concrete class. We 3145 * need to convert the method reference into a vtable index. So, for 3146 * every entry in "iftable", we create a list of vtable indices. 3147 * 3148 * Because our vtable encompasses the superclass vtable, we can use 3149 * the vtable indices from our superclass for all of the interfaces 3150 * that weren't directly implemented by us. 3151 * 3152 * Each entry in "iftable" has a pointer to the start of its set of 3153 * vtable offsets. The iftable entries in the superclass point to 3154 * storage allocated in the superclass, and the iftable entries added 3155 * for this class point to storage allocated in this class. "iftable" 3156 * is flat for fast access in a class and all of its subclasses, but 3157 * "ifviPool" is only created for the topmost implementor. 3158 */ 3159 for (int i = superIfCount; i < ifCount; i++) { 3160 /* 3161 * Note it's valid for an interface to have no methods (e.g. 3162 * java/io/Serializable). 3163 */ 3164 LOGVV("INTF: pool: %d from %s", 3165 clazz->iftable[i].clazz->virtualMethodCount, 3166 clazz->iftable[i].clazz->descriptor); 3167 poolSize += clazz->iftable[i].clazz->virtualMethodCount; 3168 } 3169 3170 if (poolSize == 0) { 3171 LOGVV("INTF: didn't find any new interfaces with methods"); 3172 result = true; 3173 goto bail; 3174 } 3175 3176 clazz->ifviPoolCount = poolSize; 3177 clazz->ifviPool = (int*) dvmLinearAlloc(clazz->classLoader, 3178 poolSize * sizeof(int*)); 3179 zapIfvipool = true; 3180 3181 /* 3182 * Fill in the vtable offsets for the interfaces that weren't part of 3183 * our superclass. 3184 */ 3185 for (int i = superIfCount; i < ifCount; i++) { 3186 ClassObject* interface; 3187 int methIdx; 3188 3189 clazz->iftable[i].methodIndexArray = clazz->ifviPool + poolOffset; 3190 interface = clazz->iftable[i].clazz; 3191 poolOffset += interface->virtualMethodCount; // end here 3192 3193 /* 3194 * For each method listed in the interface's method list, find the 3195 * matching method in our class's method list. We want to favor the 3196 * subclass over the superclass, which just requires walking 3197 * back from the end of the vtable. (This only matters if the 3198 * superclass defines a private method and this class redefines 3199 * it -- otherwise it would use the same vtable slot. In Dalvik 3200 * those don't end up in the virtual method table, so it shouldn't 3201 * matter which direction we go. We walk it backward anyway.) 3202 * 3203 * 3204 * Suppose we have the following arrangement: 3205 * public interface MyInterface 3206 * public boolean inInterface(); 3207 * public abstract class MirandaAbstract implements MirandaInterface 3208 * //public abstract boolean inInterface(); // not declared! 3209 * public boolean inAbstract() { stuff } // in vtable 3210 * public class MirandClass extends MirandaAbstract 3211 * public boolean inInterface() { stuff } 3212 * public boolean inAbstract() { stuff } // in vtable 3213 * 3214 * The javac compiler happily compiles MirandaAbstract even though 3215 * it doesn't declare all methods from its interface. When we try 3216 * to set up a vtable for MirandaAbstract, we find that we don't 3217 * have an slot for inInterface. To prevent this, we synthesize 3218 * abstract method declarations in MirandaAbstract. 3219 * 3220 * We have to expand vtable and update some things that point at it, 3221 * so we accumulate the method list and do it all at once below. 3222 */ 3223 for (methIdx = 0; methIdx < interface->virtualMethodCount; methIdx++) { 3224 Method* imeth = &interface->virtualMethods[methIdx]; 3225 int j; 3226 3227 IF_LOGVV() { 3228 char* desc = dexProtoCopyMethodDescriptor(&imeth->prototype); 3229 LOGVV("INTF: matching '%s' '%s'", imeth->name, desc); 3230 free(desc); 3231 } 3232 3233 for (j = clazz->vtableCount-1; j >= 0; j--) { 3234 if (dvmCompareMethodNamesAndProtos(imeth, clazz->vtable[j]) 3235 == 0) 3236 { 3237 LOGVV("INTF: matched at %d", j); 3238 if (!dvmIsAbstractMethod(clazz->vtable[j]) && 3239 !dvmIsPublicMethod(clazz->vtable[j])) 3240 { 3241 ALOGW("Implementation of %s.%s is not public", 3242 clazz->descriptor, clazz->vtable[j]->name); 3243 dvmThrowIllegalAccessError( 3244 "interface implementation not public"); 3245 goto bail; 3246 } 3247 clazz->iftable[i].methodIndexArray[methIdx] = j; 3248 break; 3249 } 3250 } 3251 if (j < 0) { 3252 IF_ALOGV() { 3253 char* desc = 3254 dexProtoCopyMethodDescriptor(&imeth->prototype); 3255 ALOGV("No match for '%s' '%s' in '%s' (creating miranda)", 3256 imeth->name, desc, clazz->descriptor); 3257 free(desc); 3258 } 3259 //dvmThrowRuntimeException("Miranda!"); 3260 //return false; 3261 3262 if (mirandaCount == mirandaAlloc) { 3263 mirandaAlloc += 8; 3264 if (mirandaList == NULL) { 3265 mirandaList = (Method**)dvmLinearAlloc( 3266 clazz->classLoader, 3267 mirandaAlloc * sizeof(Method*)); 3268 } else { 3269 dvmLinearReadOnly(clazz->classLoader, mirandaList); 3270 mirandaList = (Method**)dvmLinearRealloc( 3271 clazz->classLoader, 3272 mirandaList, mirandaAlloc * sizeof(Method*)); 3273 } 3274 assert(mirandaList != NULL); // mem failed + we leaked 3275 } 3276 3277 /* 3278 * These may be redundant (e.g. method with same name and 3279 * signature declared in two interfaces implemented by the 3280 * same abstract class). We can squeeze the duplicates 3281 * out here. 3282 */ 3283 int mir; 3284 for (mir = 0; mir < mirandaCount; mir++) { 3285 if (dvmCompareMethodNamesAndProtos( 3286 mirandaList[mir], imeth) == 0) 3287 { 3288 IF_LOGVV() { 3289 char* desc = dexProtoCopyMethodDescriptor( 3290 &imeth->prototype); 3291 LOGVV("MIRANDA dupe: %s and %s %s%s", 3292 mirandaList[mir]->clazz->descriptor, 3293 imeth->clazz->descriptor, 3294 imeth->name, desc); 3295 free(desc); 3296 } 3297 break; 3298 } 3299 } 3300 3301 /* point the iftable at a phantom slot index */ 3302 clazz->iftable[i].methodIndexArray[methIdx] = 3303 clazz->vtableCount + mir; 3304 LOGVV("MIRANDA: %s points at slot %d", 3305 imeth->name, clazz->vtableCount + mir); 3306 3307 /* if non-duplicate among Mirandas, add to Miranda list */ 3308 if (mir == mirandaCount) { 3309 //ALOGV("MIRANDA: holding '%s' in slot %d", 3310 // imeth->name, mir); 3311 mirandaList[mirandaCount++] = imeth; 3312 } 3313 } 3314 } 3315 } 3316 3317 if (mirandaCount != 0) { 3318 static const int kManyMirandas = 150; /* arbitrary */ 3319 Method* newVirtualMethods; 3320 Method* meth; 3321 int oldMethodCount, oldVtableCount; 3322 3323 for (int i = 0; i < mirandaCount; i++) { 3324 LOGVV("MIRANDA %d: %s.%s", i, 3325 mirandaList[i]->clazz->descriptor, mirandaList[i]->name); 3326 } 3327 if (mirandaCount > kManyMirandas) { 3328 /* 3329 * Some obfuscators like to create an interface with a huge 3330 * pile of methods, declare classes as implementing it, and then 3331 * only define a couple of methods. This leads to a rather 3332 * massive collection of Miranda methods and a lot of wasted 3333 * space, sometimes enough to blow out the LinearAlloc cap. 3334 */ 3335 ALOGD("Note: class %s has %d unimplemented (abstract) methods", 3336 clazz->descriptor, mirandaCount); 3337 } 3338 3339 /* 3340 * We found methods in one or more interfaces for which we do not 3341 * have vtable entries. We have to expand our virtualMethods 3342 * table (which might be empty) to hold some new entries. 3343 */ 3344 if (clazz->virtualMethods == NULL) { 3345 newVirtualMethods = (Method*) dvmLinearAlloc(clazz->classLoader, 3346 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount)); 3347 } else { 3348 //dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3349 newVirtualMethods = (Method*) dvmLinearRealloc(clazz->classLoader, 3350 clazz->virtualMethods, 3351 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount)); 3352 } 3353 if (newVirtualMethods != clazz->virtualMethods) { 3354 /* 3355 * Table was moved in memory. We have to run through the 3356 * vtable and fix the pointers. The vtable entries might be 3357 * pointing at superclasses, so we flip it around: run through 3358 * all locally-defined virtual methods, and fix their entries 3359 * in the vtable. (This would get really messy if sub-classes 3360 * had already been loaded.) 3361 * 3362 * Reminder: clazz->virtualMethods and clazz->virtualMethodCount 3363 * hold the virtual methods declared by this class. The 3364 * method's methodIndex is the vtable index, and is the same 3365 * for all sub-classes (and all super classes in which it is 3366 * defined). We're messing with these because the Miranda 3367 * stuff makes it look like the class actually has an abstract 3368 * method declaration in it. 3369 */ 3370 LOGVV("MIRANDA fixing vtable pointers"); 3371 dvmLinearReadWrite(clazz->classLoader, clazz->vtable); 3372 Method* meth = newVirtualMethods; 3373 for (int i = 0; i < clazz->virtualMethodCount; i++, meth++) 3374 clazz->vtable[meth->methodIndex] = meth; 3375 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 3376 } 3377 3378 oldMethodCount = clazz->virtualMethodCount; 3379 clazz->virtualMethods = newVirtualMethods; 3380 clazz->virtualMethodCount += mirandaCount; 3381 3382 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3383 3384 /* 3385 * We also have to expand the vtable. 3386 */ 3387 assert(clazz->vtable != NULL); 3388 clazz->vtable = (Method**) dvmLinearRealloc(clazz->classLoader, 3389 clazz->vtable, 3390 sizeof(Method*) * (clazz->vtableCount + mirandaCount)); 3391 if (clazz->vtable == NULL) { 3392 assert(false); 3393 goto bail; 3394 } 3395 zapVtable = true; 3396 3397 oldVtableCount = clazz->vtableCount; 3398 clazz->vtableCount += mirandaCount; 3399 3400 /* 3401 * Now we need to create the fake methods. We clone the abstract 3402 * method definition from the interface and then replace a few 3403 * things. 3404 * 3405 * The Method will be an "abstract native", with nativeFunc set to 3406 * dvmAbstractMethodStub(). 3407 */ 3408 meth = clazz->virtualMethods + oldMethodCount; 3409 for (int i = 0; i < mirandaCount; i++, meth++) { 3410 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 3411 cloneMethod(meth, mirandaList[i]); 3412 meth->clazz = clazz; 3413 meth->accessFlags |= ACC_MIRANDA; 3414 meth->methodIndex = (u2) (oldVtableCount + i); 3415 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3416 3417 /* point the new vtable entry at the new method */ 3418 clazz->vtable[oldVtableCount + i] = meth; 3419 } 3420 3421 dvmLinearReadOnly(clazz->classLoader, mirandaList); 3422 dvmLinearFree(clazz->classLoader, mirandaList); 3423 3424 } 3425 3426 /* 3427 * TODO? 3428 * Sort the interfaces by number of declared methods. All we really 3429 * want is to get the interfaces with zero methods at the end of the 3430 * list, so that when we walk through the list during invoke-interface 3431 * we don't examine interfaces that can't possibly be useful. 3432 * 3433 * The set will usually be small, so a simple insertion sort works. 3434 * 3435 * We have to be careful not to change the order of two interfaces 3436 * that define the same method. (Not a problem if we only move the 3437 * zero-method interfaces to the end.) 3438 * 3439 * PROBLEM: 3440 * If we do this, we will no longer be able to identify super vs. 3441 * current class interfaces by comparing clazz->super->iftableCount. This 3442 * breaks anything that only wants to find interfaces declared directly 3443 * by the class (dvmFindStaticFieldHier, ReferenceType.Interfaces, 3444 * dvmDbgOutputAllInterfaces, etc). Need to provide a workaround. 3445 * 3446 * We can sort just the interfaces implemented directly by this class, 3447 * but that doesn't seem like it would provide much of an advantage. I'm 3448 * not sure this is worthwhile. 3449 * 3450 * (This has been made largely obsolete by the interface cache mechanism.) 3451 */ 3452 3453 //dvmDumpClass(clazz); 3454 3455 result = true; 3456 3457 bail: 3458 if (zapIftable) 3459 dvmLinearReadOnly(clazz->classLoader, clazz->iftable); 3460 if (zapVtable) 3461 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 3462 if (zapIfvipool) 3463 dvmLinearReadOnly(clazz->classLoader, clazz->ifviPool); 3464 return result; 3465 } 3466 3467 3468 /* 3469 * Provide "stub" implementations for methods without them. 3470 * 3471 * Currently we provide an implementation for all abstract methods that 3472 * throws an AbstractMethodError exception. This allows us to avoid an 3473 * explicit check for abstract methods in every virtual call. 3474 * 3475 * NOTE: for Miranda methods, the method declaration is a clone of what 3476 * was found in the interface class. That copy may already have had the 3477 * function pointer filled in, so don't be surprised if it's not NULL. 3478 * 3479 * NOTE: this sets the "native" flag, giving us an "abstract native" method, 3480 * which is nonsensical. Need to make sure that this doesn't escape the 3481 * VM. We can either mask it out in reflection calls, or copy "native" 3482 * into the high 16 bits of accessFlags and check that internally. 3483 */ 3484 static bool insertMethodStubs(ClassObject* clazz) 3485 { 3486 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 3487 3488 Method* meth; 3489 int i; 3490 3491 meth = clazz->virtualMethods; 3492 for (i = 0; i < clazz->virtualMethodCount; i++, meth++) { 3493 if (dvmIsAbstractMethod(meth)) { 3494 assert(meth->insns == NULL); 3495 assert(meth->nativeFunc == NULL || 3496 meth->nativeFunc == (DalvikBridgeFunc)dvmAbstractMethodStub); 3497 3498 meth->accessFlags |= ACC_NATIVE; 3499 meth->nativeFunc = (DalvikBridgeFunc) dvmAbstractMethodStub; 3500 } 3501 } 3502 3503 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3504 return true; 3505 } 3506 3507 3508 /* 3509 * Swap two instance fields. 3510 */ 3511 static inline void swapField(InstField* pOne, InstField* pTwo) 3512 { 3513 InstField swap; 3514 3515 LOGVV(" --- swap '%s' and '%s'", pOne->name, pTwo->name); 3516 swap = *pOne; 3517 *pOne = *pTwo; 3518 *pTwo = swap; 3519 } 3520 3521 /* 3522 * Assign instance fields to u4 slots. 3523 * 3524 * The top portion of the instance field area is occupied by the superclass 3525 * fields, the bottom by the fields for this class. 3526 * 3527 * "long" and "double" fields occupy two adjacent slots. On some 3528 * architectures, 64-bit quantities must be 64-bit aligned, so we need to 3529 * arrange fields (or introduce padding) to ensure this. We assume the 3530 * fields of the topmost superclass (i.e. Object) are 64-bit aligned, so 3531 * we can just ensure that the offset is "even". To avoid wasting space, 3532 * we want to move non-reference 32-bit fields into gaps rather than 3533 * creating pad words. 3534 * 3535 * In the worst case we will waste 4 bytes, but because objects are 3536 * allocated on >= 64-bit boundaries, those bytes may well be wasted anyway 3537 * (assuming this is the most-derived class). 3538 * 3539 * Pad words are not represented in the field table, so the field table 3540 * itself does not change size. 3541 * 3542 * The number of field slots determines the size of the object, so we 3543 * set that here too. 3544 * 3545 * This function feels a little more complicated than I'd like, but it 3546 * has the property of moving the smallest possible set of fields, which 3547 * should reduce the time required to load a class. 3548 * 3549 * NOTE: reference fields *must* come first, or precacheReferenceOffsets() 3550 * will break. 3551 */ 3552 static bool computeFieldOffsets(ClassObject* clazz) 3553 { 3554 int fieldOffset; 3555 int i, j; 3556 3557 dvmLinearReadWrite(clazz->classLoader, clazz->ifields); 3558 3559 if (clazz->super != NULL) 3560 fieldOffset = clazz->super->objectSize; 3561 else 3562 fieldOffset = OFFSETOF_MEMBER(DataObject, instanceData); 3563 3564 LOGVV("--- computeFieldOffsets '%s'", clazz->descriptor); 3565 3566 //ALOGI("OFFSETS fieldCount=%d", clazz->ifieldCount); 3567 //ALOGI("dataobj, instance: %d", offsetof(DataObject, instanceData)); 3568 //ALOGI("classobj, access: %d", offsetof(ClassObject, accessFlags)); 3569 //ALOGI("super=%p, fieldOffset=%d", clazz->super, fieldOffset); 3570 3571 /* 3572 * Start by moving all reference fields to the front. 3573 */ 3574 clazz->ifieldRefCount = 0; 3575 j = clazz->ifieldCount - 1; 3576 for (i = 0; i < clazz->ifieldCount; i++) { 3577 InstField* pField = &clazz->ifields[i]; 3578 char c = pField->signature[0]; 3579 3580 if (c != '[' && c != 'L') { 3581 /* This isn't a reference field; see if any reference fields 3582 * follow this one. If so, we'll move it to this position. 3583 * (quicksort-style partitioning) 3584 */ 3585 while (j > i) { 3586 InstField* refField = &clazz->ifields[j--]; 3587 char rc = refField->signature[0]; 3588 3589 if (rc == '[' || rc == 'L') { 3590 /* Here's a reference field that follows at least one 3591 * non-reference field. Swap it with the current field. 3592 * (When this returns, "pField" points to the reference 3593 * field, and "refField" points to the non-ref field.) 3594 */ 3595 swapField(pField, refField); 3596 3597 /* Fix the signature. 3598 */ 3599 c = rc; 3600 3601 clazz->ifieldRefCount++; 3602 break; 3603 } 3604 } 3605 /* We may or may not have swapped a field. 3606 */ 3607 } else { 3608 /* This is a reference field. 3609 */ 3610 clazz->ifieldRefCount++; 3611 } 3612 3613 /* 3614 * If we've hit the end of the reference fields, break. 3615 */ 3616 if (c != '[' && c != 'L') 3617 break; 3618 3619 pField->byteOffset = fieldOffset; 3620 fieldOffset += sizeof(u4); 3621 LOGVV(" --- offset1 '%s'=%d", pField->name,pField->byteOffset); 3622 } 3623 3624 /* 3625 * Now we want to pack all of the double-wide fields together. If we're 3626 * not aligned, though, we want to shuffle one 32-bit field into place. 3627 * If we can't find one, we'll have to pad it. 3628 */ 3629 if (i != clazz->ifieldCount && (fieldOffset & 0x04) != 0) { 3630 LOGVV(" +++ not aligned"); 3631 3632 InstField* pField = &clazz->ifields[i]; 3633 char c = pField->signature[0]; 3634 3635 if (c != 'J' && c != 'D') { 3636 /* 3637 * The field that comes next is 32-bit, so just advance past it. 3638 */ 3639 assert(c != '[' && c != 'L'); 3640 pField->byteOffset = fieldOffset; 3641 fieldOffset += sizeof(u4); 3642 i++; 3643 LOGVV(" --- offset2 '%s'=%d", 3644 pField->name, pField->byteOffset); 3645 } else { 3646 /* 3647 * Next field is 64-bit, so search for a 32-bit field we can 3648 * swap into it. 3649 */ 3650 bool found = false; 3651 j = clazz->ifieldCount - 1; 3652 while (j > i) { 3653 InstField* singleField = &clazz->ifields[j--]; 3654 char rc = singleField->signature[0]; 3655 3656 if (rc != 'J' && rc != 'D') { 3657 swapField(pField, singleField); 3658 //c = rc; 3659 LOGVV(" +++ swapped '%s' for alignment", 3660 pField->name); 3661 pField->byteOffset = fieldOffset; 3662 fieldOffset += sizeof(u4); 3663 LOGVV(" --- offset3 '%s'=%d", 3664 pField->name, pField->byteOffset); 3665 found = true; 3666 i++; 3667 break; 3668 } 3669 } 3670 if (!found) { 3671 ALOGV(" +++ inserting pad field in '%s'", clazz->descriptor); 3672 fieldOffset += sizeof(u4); 3673 } 3674 } 3675 } 3676 3677 /* 3678 * Alignment is good, shuffle any double-wide fields forward, and 3679 * finish assigning field offsets to all fields. 3680 */ 3681 assert(i == clazz->ifieldCount || (fieldOffset & 0x04) == 0); 3682 j = clazz->ifieldCount - 1; 3683 for ( ; i < clazz->ifieldCount; i++) { 3684 InstField* pField = &clazz->ifields[i]; 3685 char c = pField->signature[0]; 3686 3687 if (c != 'D' && c != 'J') { 3688 /* This isn't a double-wide field; see if any double fields 3689 * follow this one. If so, we'll move it to this position. 3690 * (quicksort-style partitioning) 3691 */ 3692 while (j > i) { 3693 InstField* doubleField = &clazz->ifields[j--]; 3694 char rc = doubleField->signature[0]; 3695 3696 if (rc == 'D' || rc == 'J') { 3697 /* Here's a double-wide field that follows at least one 3698 * non-double field. Swap it with the current field. 3699 * (When this returns, "pField" points to the reference 3700 * field, and "doubleField" points to the non-double field.) 3701 */ 3702 swapField(pField, doubleField); 3703 c = rc; 3704 3705 break; 3706 } 3707 } 3708 /* We may or may not have swapped a field. 3709 */ 3710 } else { 3711 /* This is a double-wide field, leave it be. 3712 */ 3713 } 3714 3715 pField->byteOffset = fieldOffset; 3716 LOGVV(" --- offset4 '%s'=%d", pField->name,pField->byteOffset); 3717 fieldOffset += sizeof(u4); 3718 if (c == 'J' || c == 'D') 3719 fieldOffset += sizeof(u4); 3720 } 3721 3722 #ifndef NDEBUG 3723 /* Make sure that all reference fields appear before 3724 * non-reference fields, and all double-wide fields are aligned. 3725 */ 3726 j = 0; // seen non-ref 3727 for (i = 0; i < clazz->ifieldCount; i++) { 3728 InstField *pField = &clazz->ifields[i]; 3729 char c = pField->signature[0]; 3730 3731 if (c == 'D' || c == 'J') { 3732 assert((pField->byteOffset & 0x07) == 0); 3733 } 3734 3735 if (c != '[' && c != 'L') { 3736 if (!j) { 3737 assert(i == clazz->ifieldRefCount); 3738 j = 1; 3739 } 3740 } else if (j) { 3741 assert(false); 3742 } 3743 } 3744 if (!j) { 3745 assert(clazz->ifieldRefCount == clazz->ifieldCount); 3746 } 3747 #endif 3748 3749 /* 3750 * We map a C struct directly on top of java/lang/Class objects. Make 3751 * sure we left enough room for the instance fields. 3752 */ 3753 assert(!dvmIsTheClassClass(clazz) || (size_t)fieldOffset < 3754 OFFSETOF_MEMBER(ClassObject, instanceData) + sizeof(clazz->instanceData)); 3755 3756 clazz->objectSize = fieldOffset; 3757 3758 dvmLinearReadOnly(clazz->classLoader, clazz->ifields); 3759 return true; 3760 } 3761 3762 /* 3763 * The class failed to initialize on a previous attempt, so we want to throw 3764 * a NoClassDefFoundError (v2 2.17.5). The exception to this rule is if we 3765 * failed in verification, in which case v2 5.4.1 says we need to re-throw 3766 * the previous error. 3767 */ 3768 static void throwEarlierClassFailure(ClassObject* clazz) 3769 { 3770 ALOGI("Rejecting re-init on previously-failed class %s v=%p", 3771 clazz->descriptor, clazz->verifyErrorClass); 3772 3773 if (clazz->verifyErrorClass == NULL) { 3774 dvmThrowNoClassDefFoundError(clazz->descriptor); 3775 } else { 3776 dvmThrowExceptionWithClassMessage(clazz->verifyErrorClass, 3777 clazz->descriptor); 3778 } 3779 } 3780 3781 /* 3782 * Initialize any static fields whose values are stored in 3783 * the DEX file. This must be done during class initialization. 3784 */ 3785 static void initSFields(ClassObject* clazz) 3786 { 3787 Thread* self = dvmThreadSelf(); /* for dvmReleaseTrackedAlloc() */ 3788 DexFile* pDexFile; 3789 const DexClassDef* pClassDef; 3790 const DexEncodedArray* pValueList; 3791 EncodedArrayIterator iterator; 3792 int i; 3793 3794 if (clazz->sfieldCount == 0) { 3795 return; 3796 } 3797 if (clazz->pDvmDex == NULL) { 3798 /* generated class; any static fields should already be set up */ 3799 ALOGV("Not initializing static fields in %s", clazz->descriptor); 3800 return; 3801 } 3802 pDexFile = clazz->pDvmDex->pDexFile; 3803 3804 pClassDef = dexFindClass(pDexFile, clazz->descriptor); 3805 assert(pClassDef != NULL); 3806 3807 pValueList = dexGetStaticValuesList(pDexFile, pClassDef); 3808 if (pValueList == NULL) { 3809 return; 3810 } 3811 3812 dvmEncodedArrayIteratorInitialize(&iterator, pValueList, clazz); 3813 3814 /* 3815 * Iterate over the initial values array, setting the corresponding 3816 * static field for each array element. 3817 */ 3818 3819 for (i = 0; dvmEncodedArrayIteratorHasNext(&iterator); i++) { 3820 AnnotationValue value; 3821 bool parsed = dvmEncodedArrayIteratorGetNext(&iterator, &value); 3822 StaticField* sfield = &clazz->sfields[i]; 3823 const char* descriptor = sfield->signature; 3824 bool isObj = false; 3825 3826 if (! parsed) { 3827 /* 3828 * TODO: Eventually verification should attempt to ensure 3829 * that this can't happen at least due to a data integrity 3830 * problem. 3831 */ 3832 ALOGE("Static initializer parse failed for %s at index %d", 3833 clazz->descriptor, i); 3834 dvmAbort(); 3835 } 3836 3837 /* Verify that the value we got was of a valid type. */ 3838 3839 switch (descriptor[0]) { 3840 case 'Z': parsed = (value.type == kDexAnnotationBoolean); break; 3841 case 'B': parsed = (value.type == kDexAnnotationByte); break; 3842 case 'C': parsed = (value.type == kDexAnnotationChar); break; 3843 case 'S': parsed = (value.type == kDexAnnotationShort); break; 3844 case 'I': parsed = (value.type == kDexAnnotationInt); break; 3845 case 'J': parsed = (value.type == kDexAnnotationLong); break; 3846 case 'F': parsed = (value.type == kDexAnnotationFloat); break; 3847 case 'D': parsed = (value.type == kDexAnnotationDouble); break; 3848 case '[': parsed = (value.type == kDexAnnotationNull); break; 3849 case 'L': { 3850 switch (value.type) { 3851 case kDexAnnotationNull: { 3852 /* No need for further tests. */ 3853 break; 3854 } 3855 case kDexAnnotationString: { 3856 parsed = 3857 (strcmp(descriptor, "Ljava/lang/String;") == 0); 3858 isObj = true; 3859 break; 3860 } 3861 case kDexAnnotationType: { 3862 parsed = 3863 (strcmp(descriptor, "Ljava/lang/Class;") == 0); 3864 isObj = true; 3865 break; 3866 } 3867 default: { 3868 parsed = false; 3869 break; 3870 } 3871 } 3872 break; 3873 } 3874 default: { 3875 parsed = false; 3876 break; 3877 } 3878 } 3879 3880 if (parsed) { 3881 /* 3882 * All's well, so store the value. 3883 */ 3884 if (isObj) { 3885 dvmSetStaticFieldObject(sfield, (Object*)value.value.l); 3886 dvmReleaseTrackedAlloc((Object*)value.value.l, self); 3887 } else { 3888 /* 3889 * Note: This always stores the full width of a 3890 * JValue, even though most of the time only the first 3891 * word is needed. 3892 */ 3893 sfield->value = value.value; 3894 } 3895 } else { 3896 /* 3897 * Something up above had a problem. TODO: See comment 3898 * above the switch about verfication. 3899 */ 3900 ALOGE("Bogus static initialization: value type %d in field type " 3901 "%s for %s at index %d", 3902 value.type, descriptor, clazz->descriptor, i); 3903 dvmAbort(); 3904 } 3905