diff options
author | Tom Tromey <tromey@gcc.gnu.org> | 2007-01-09 19:58:05 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2007-01-09 19:58:05 +0000 |
commit | 97b8365cafc3a344a22d3980b8ed885f5c6d8357 (patch) | |
tree | 996a5f57d4a68c53473382e45cb22f574cb3e4db /libjava/java/lang/natClassLoader.cc | |
parent | c648dedbde727ca3f883bb5fd773aa4af70d3369 (diff) | |
download | gcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.zip gcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.tar.gz gcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.tar.bz2 |
Merged gcj-eclipse branch to trunk.
From-SVN: r120621
Diffstat (limited to 'libjava/java/lang/natClassLoader.cc')
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index b05c0b1..9c1a6a2 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -180,6 +180,41 @@ _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader) // _Jv_RegisterNewClasses() are of Type 2. +// Check that the file we're trying to load has been compiled with a +// compatible version of gcj. In previous versions of libgcj we +// silently failed to register classes of an incompatible ABI version, +// but this was totally bogus. +void +_Jv_CheckABIVersion (unsigned long value) +{ + // We are compatible with GCJ 4.0.0 BC-ABI classes. This release used a + // different format for the version ID string. + if (value == OLD_GCJ_40_BC_ABI_VERSION) + return; + + // The 20 low-end bits are used for the version number. + unsigned long version = value & 0xfffff; + + if (value & FLAG_BINARYCOMPAT_ABI) + { + int abi_rev = version % 100; + int abi_ver = version - abi_rev; + // We are compatible with abi_rev 0 and 1. + if (abi_ver == GCJ_40_BC_ABI_VERSION && abi_rev <= 1) + return; + } + else + { + // C++ ABI + if (version == GCJ_CXX_ABI_VERSION) + return; + } + + throw new ::java::lang::ClassFormatError + (JvNewStringLatin1 ("Library compiled with later ABI version than" + " this version of libgcj supports")); +} + // This function is called many times during startup, before main() is // run. At that point in time we know for certain we are running // single-threaded, so we don't need to lock when adding classes to the @@ -194,8 +229,8 @@ _Jv_RegisterClasses (const jclass *classes) { jclass klass = *classes; - if (_Jv_CheckABIVersion ((unsigned long) klass->next_or_version)) - (*_Jv_RegisterClassHook) (klass); + _Jv_CheckABIVersion ((unsigned long) klass->next_or_version); + (*_Jv_RegisterClassHook) (klass); } } @@ -211,32 +246,37 @@ _Jv_RegisterClasses_Counted (const jclass * classes, size_t count) { jclass klass = classes[i]; - if (_Jv_CheckABIVersion ((unsigned long) klass->next_or_version)) - (*_Jv_RegisterClassHook) (klass); + _Jv_CheckABIVersion ((unsigned long) klass->next_or_version); + (*_Jv_RegisterClassHook) (klass); } } // Create a class on the heap from an initializer struct. -jclass +inline jclass _Jv_NewClassFromInitializer (const char *class_initializer) { + const unsigned long version + = ((unsigned long) + ((::java::lang::Class *)class_initializer)->next_or_version); + _Jv_CheckABIVersion (version); + /* We create an instance of java::lang::Class and copy all of its fields except the first word (the vtable pointer) from CLASS_INITIALIZER. This first word is pre-initialized by _Jv_AllocObj, and we don't want to overwrite it. */ - + jclass new_class - = (jclass)_Jv_AllocObj (sizeof (java::lang::Class), - &java::lang::Class::class$); + = (jclass)_Jv_AllocObj (sizeof (::java::lang::Class), + &::java::lang::Class::class$); const char *src = class_initializer + sizeof (void*); char *dst = (char*)new_class + sizeof (void*); - size_t len = sizeof (*new_class) - sizeof (void*); + size_t len = (::java::lang::Class::initializerSize (version) + - sizeof (void*)); memcpy (dst, src, len); - + new_class->engine = &_Jv_soleIndirectCompiledEngine; - - if (_Jv_CheckABIVersion ((unsigned long) new_class->next_or_version)) - (*_Jv_RegisterClassHook) (new_class); + + (*_Jv_RegisterClassHook) (new_class); return new_class; } |