1 /*
2 * @(#)classresolver.c 1.19 02/09/27
3 *
4 * Copyright 1995-1998 by Sun Microsystems, Inc.,
5 * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
6 * All rights reserved.
7 *
8 * This software is the confidential and proprietary information
9 * of Sun Microsystems, Inc. ("Confidential Information"). You
10 * shall not disclose such Confidential Information and shall use
11 * it only in accordance with the terms of the license agreement
12 * you entered into with Sun.
13 * Use is subject to license terms.
14 */
16 /*=========================================================================
17 * SYSTEM: Verifier
18 * SUBSYSTEM: class resolver.c.
19 * FILE: classresolver.c
20 * OVERVIEW: Routines for loading and resolving class definitions.
21 * These routines should not be depending upon the interpreter
22 * or the garbage collector.
23 * AUTHOR: Sheng Liang, Sun Microsystems, Inc.
24 * Modifications for CLDC compliance checks,
25 * Tasneem Sayeed, Sun Microsystems
26 * Frank Yellin, Sun Microsystems
27 *=======================================================================*/
29 /*=========================================================================
30 * Include files
31 *=======================================================================*/
33 #include <ctype.h>
34 #include <string.h>
35 #include <sys/types.h>
36 #include <fcntl.h>
37 #include <sys/stat.h>
38 #include <stdlib.h>
47 /*=========================================================================
48 * Globals and extern declarations
49 *=======================================================================*/
78 /* An Explanation of Class-related Locks
79 *
80 * There are two global locks related to class loading:
81 *
82 * LOADCLASS_LOCK: ensures that only one thread is loading a class at
83 * a given time. This eliminates the possibility of two threads loading
84 * classes with the same name and same loader.
85 *
86 * BINCLASS_LOCK: ensures that only one thread is updating the global
87 * class table (binclasses). This lock is also grabbed by the GC to ensure
88 * that the GC always sees a valid global class table state.
89 *
90 * In addition, each class may have its own associated locks that are
91 * created with monitorEnter(). ResolveClass, for example, need to
92 * first grab this lock to ensure that the class is resolved only by
93 * one thread, rather than simultaneously by multiple threads.
94 */
101 {
108 sfb++;
109 }
111 }
113 int
115 {
121 }
127 nslots++;
128 fb++;
129 }
132 }
134 }
137 nslots++;
138 }
143 }
146 }
148 int
150 {
156 }
158 #if 0
161 {
163 src++;
168 }
169 #endif
173 {
184 /* Do nothing. Handled when the class is loaded. */
188 }
189 #ifdef UNUSED
195 }
196 #endif
197 }
200 }
203 #ifdef UNUSED
207 else
211 #endif
213 }
218 {
229 FINALIZER_METHOD_SIGNATURE);
235 }
238 /* We don't really need to built a method table for interfaces. */
242 /* Each method's offset is its index in the interface */
245 }
247 }
254 /* Inherit one's parent's finalizer, if it has one */
261 }
274 /* If this item has its own finalizer method, grab it */
278 }
280 }
286 /* Private methods are not inherited outside of the class. */
289 /* Package-private methods are not inherited outside of the
290 package. */
296 }
297 /*
298 jio_fprintf(stderr, "!!!%s.%s\n", cbName(cb), mb->fb.name);
299 */
300 }
301 }
305 mslot++;
306 }
307 }
311 }
313 /*
314 * This should be the only place that method tables are
315 * allocated. We allocate more than we need here and mask the
316 * resulting pointer because the methodtable pointer field in
317 * object handles is overloaded and sometimes hold array types
318 * and array lengths. We must ensure that method table pointers
319 * are allocated on an appropriate boundary so we don't lose any
320 * address bits when we mask off the type portion of the pointer.
321 */
328 }
343 }
344 }
349 }
354 {
358 /* classes that don't implement their own interfaces can just inherit
359 * their parents imethodtable. */
361 /* We can preinitialize the imethodtable of java.lang.Object */
367 }
379 /* Resolve all the interfaces that this class implements, and
380 * make sure that they all really are interfaces
381 *
382 * icount will total all the interfaces that this class implements,
383 * (include interfaces implemented by our superclass, and by
384 * interfaces that we implement.)
385 * mcount will total the total amount of space (in sizeof(long)) for
386 * which we'll have to allocate space for in the offsets table.
387 */
398 }
404 }
406 {
413 }
418 }
422 /* Start filling in the table. */
427 icount++;
428 }
430 /* We can copy our superclass's offset table. The offsets
431 will stay the same. */
436 }
438 /* Add the interfaces that we implement, either directly, or
439 * because those interfaces implement other interfaces. */
446 }
448 /* Delete duplicates from the table. This is very rare, so it can
449 * be quite inefficient. */
454 /* We have an overlap. Item i is a duplicate. Delete from
455 * the table */
458 icount--;
461 }
462 }
463 }
466 /* Nothing more to do for interfaces or abstract classes */
468 }
470 /* For each additional interface . . . */
472 /* The table length is the number of interface methods */
479 /* Look at each interface method */
486 /* Find the class method that implements the interface
487 * method */
496 }
497 }
498 /*
499 if (k == -1) {
500 *detail = "Unimplemented interface method";
501 return JAVAPKG "IncompatibleClassChangeError";
502 }
503 */
504 }
505 }
506 }
508 }
509 }
514 {
520 }
525 {
534 }
535 }
537 }
541 {
549 }
551 /*
552 * Detect class circularities from InitializeClass()
553 */
555 static void
557 {
561 }
563 static void
565 {
569 }
571 static bool_t
573 {
579 }
581 }
585 {
588 bool_t noLoader;
596 #ifndef TRIMMED
599 #endif
604 }
606 /* Temporarily disable class circularity checks */
610 /* Note: don't bother restoring on (fatal) error during bootstrap */
614 classJavaLangString =
619 }
620 /* classJavaLangThreadDeath =
621 FindStickySystemClass(NULL, JAVAPKG "ThreadDeath", TRUE);
622 if (classJavaLangThreadDeath == 0) {
623 *detail = JAVAPKG "ThreadDeath";
624 return JAVAPKG "NoClassDefFoundError";
625 }
626 */
627 classJavaLangThrowable =
632 }
633 /*
634 classJavaLangException =
635 FindStickySystemClass(NULL, JAVAPKG "Exception", TRUE);
636 if (classJavaLangException == 0) {
637 *detail = JAVAPKG "Exception";
638 return JAVAPKG "NoClassDefFoundError";
639 }
640 classJavaLangError =
641 FindStickySystemClass(NULL, JAVAPKG "Error", TRUE);
642 if (classJavaLangError == 0) {
643 *detail = JAVAPKG "Error";
644 return JAVAPKG "NoClassDefFoundError";
645 }
646 classJavaLangRuntimeException =
647 FindStickySystemClass(NULL, JAVAPKG "RuntimeException", TRUE);
648 if (classJavaLangRuntimeException == 0) {
649 *detail = JAVAPKG "RuntimeException";
650 return JAVAPKG "NoClassDefFoundError";
651 }
652 interfaceJavaLangCloneable =
653 FindStickySystemClass(NULL, JAVAPKG "Cloneable", TRUE);
654 if (interfaceJavaLangCloneable == 0) {
655 *detail = JAVAPKG "Cloneable";
656 return JAVAPKG "NoClassDefFoundError";
657 }
658 interfaceJavaIoSerializable =
659 FindStickySystemClass(NULL, "java/io/Serializable", TRUE);
660 if (interfaceJavaIoSerializable == 0) {
661 *detail = "java/io/Serializable";
662 return JAVAPKG "NoClassDefFoundError";
663 }
664 */
665 /* Restore stack for class circularity checks */
671 }
677 }
680 }
681 }
684 /* Check for class definition circularities */
691 }
696 /* Conversion for Japanese file names */
704 /* Don't allow a class to have a superclass it can't access */
707 }
708 }
718 }
724 }
725 }
728 /* Be very careful, since not verified yet. . .
729 */
749 }
752 // if (iname == NULL || !IsLegalClassname(iname, FALSE)) {
753 // *detail = "Bad interface name";
754 // return JAVAPKG "ClassFormatError";
755 // }
757 {
764 }
777 }
778 }
779 }
783 /* Make sure we know what classJavaLangClass is, and that it's method table
784 * is filled in.
785 */
787 classJavaLangClass =
791 }
792 }
794 /* The following may not do anything useful if classJavaLangClass hasn't
795 * been completely resolved. But we clean up in ResolveClass
796 */
800 }
804 {
813 }
819 }
822 /* If this object has a superclass. . . */
828 }
829 }
832 }
843 }
844 }
845 }
850 #ifndef TRIMMED
853 #endif
859 }
862 /* May return "OutOfMemoryError" or "InternalError" */
866 }
871 }
880 }
881 }
885 /* We need this for bootstrapping. We can't set the Handle's class block
886 * pointer in Object or Class until Class has been resolved.
887 */
894 }
897 }
899 }
901 static bool_t
903 {
909 /* Don't need to initialize or verify array or primitive classes */
920 }
925 }
928 }
931 }
933 }
936 /* Find an already loaded class with the given name. If no such class exists
937 * then return 0.
938 */
940 #ifdef DEBUG
941 void
943 {
951 }
953 }
954 #endif
958 {
977 }
978 }
985 }
986 }
991 }
993 }
995 /* We attempt to resolve it, also, if the "resolve" argument is true.
996 * Otherwise, we only perform a minimal initialization on it, such that
997 * it points to its superclass, which points to its superclass. . . .
998 */
1002 {
1005 /* Check for underlying error already posted */
1009 }
1013 /* Check for underlying error already posted */
1017 }
1018 }
1020 }
1022 /* Find the class with the given name.
1023 * If "resolve" is true, then we completely resolve the class. Otherwise,
1024 * we only make sure that it points to its superclass, which points to its
1025 * superclass, . . . .
1026 */
1029 ClassClass *
1031 {
1033 }
1036 /*
1037 * lock_classes and unlock_classes are exported by the JIT interface,
1038 * but no longer used anywhere else. It grabs both locks to ensure
1039 * backward compatibility with 1.0.2.
1040 */
1041 void
1043 {
1046 }
1048 void
1050 {
1053 }
1060 ClassClass *
1063 {
1067 }
1069 /*
1070 * FindStickySystemClass is a variant of FindClassFromClass that makes the
1071 * class sticky (immune to class GC) if the class can be found. It is only
1072 * used on system classes, i.e. classes with no class loader, so it's
1073 * equivalent to FindClassFromClass with "from" argument 0. It returns 0
1074 * if the class can't be found, and like FindClass assumes that the caller
1075 * will deal with that. Note that until the class has been made sticky it
1076 * must be kept somewhere where GC will find it.
1077 */
1078 ClassClass *
1080 {
1084 }
1086 }
1088 /* Find the array class with the specified name. */
1103 /* quick optimization if we know that we don't need a class loader */
1107 }
1111 /* Strip off all the initial SIGNATURE_ARRAY's to determine the depth,
1112 * and also what's left. When we're done, name_p points at the first
1113 * non-character, and depth is the count of the array depth
1114 */
1118 /* Look at the character to determine what type of array we have. */
1130 }
1147 /* loader should either be fromLoader or NULL. */
1154 }
1160 /* Create the fake array class corresponding to this.
1161 */
1163 }
1166 }
1168 /*
1169 * Convert a name and type to a hash code
1170 *
1171 * We make copies of all strings that go into the hash table
1172 * in case the class that is the source of the strings being
1173 * inserted is eventually unloaded.
1174 */
1176 {
1190 }
1194 }
1196 /*
1197 * Pseudo-classes to represent primitive Java types.
1198 */
1227 };
1229 #define PRIMITIVE_TYPE_COUNT \
1230 (sizeof (primitive_types) / sizeof (primitive_types[0]))
1232 #define GET_PRIMITIVE_CLASS(nm) \
1233 (class_##nm ? class_##nm : FindPrimitiveClass(#nm))
1235 ClassClass *
1237 {
1256 }
1258 }
1259 }
1261 }
1263 static void
1265 {
1269 }