mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-12 19:50:04 +08:00
natClassLoader.cc (_Jv_RegisterInitiatingLoader): Check loading constraints.
* java/lang/natClassLoader.cc (_Jv_RegisterInitiatingLoader): Check loading constraints. (_Jv_CheckOrCreateLoadingConstraint): New function. * java/lang/ClassLoader.java (loadingConstraints): New field. * link.cc (_Jv_Linker::find_field): Use _Jv_CheckOrCreateLoadingConstraint. (_Jv_Linker::check_loading_constraints): New function. (_Jv_Linker::resolve_method_entry): Use check_loading_constraints. (_Jv_Linker::append_partial_itable): Likewise. (_Jv_Linker::layout_vtable_methods): Likewise. * include/jvm.h (_Jv_Linker::check_loading_constraints): Declare. (_Jv_CheckOrCreateLoadingConstraint): Declare. From-SVN: r133172
This commit is contained in:
parent
5f5f0635f1
commit
2599b56f41
@ -1,3 +1,19 @@
|
||||
2008-03-13 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* java/lang/natClassLoader.cc (_Jv_RegisterInitiatingLoader):
|
||||
Check loading constraints.
|
||||
(_Jv_CheckOrCreateLoadingConstraint): New function.
|
||||
* java/lang/ClassLoader.java (loadingConstraints): New field.
|
||||
* link.cc (_Jv_Linker::find_field): Use
|
||||
_Jv_CheckOrCreateLoadingConstraint.
|
||||
(_Jv_Linker::check_loading_constraints): New function.
|
||||
(_Jv_Linker::resolve_method_entry): Use
|
||||
check_loading_constraints.
|
||||
(_Jv_Linker::append_partial_itable): Likewise.
|
||||
(_Jv_Linker::layout_vtable_methods): Likewise.
|
||||
* include/jvm.h (_Jv_Linker::check_loading_constraints): Declare.
|
||||
(_Jv_CheckOrCreateLoadingConstraint): Declare.
|
||||
|
||||
2008-03-10 Jim Meyering <meyering@redhat.com>
|
||||
|
||||
Don't leak upon failed realloc.
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// jvm.h - Header file for private implementation information. -*- c++ -*-
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@ -265,6 +265,7 @@ private:
|
||||
jclass, jclass *);
|
||||
static _Jv_Field *find_field(jclass, jclass, jclass *, _Jv_Utf8Const *,
|
||||
_Jv_Utf8Const *);
|
||||
static void check_loading_constraints (_Jv_Method *, jclass, jclass);
|
||||
static void prepare_constant_time_tables(jclass);
|
||||
static jshort get_interfaces(jclass, _Jv_ifaces *);
|
||||
static void link_symbol_table(jclass);
|
||||
@ -557,6 +558,9 @@ extern void _Jv_CallAnyMethodA (jobject obj,
|
||||
jboolean is_jni_call = true,
|
||||
jclass iface = NULL);
|
||||
|
||||
extern void _Jv_CheckOrCreateLoadingConstraint (jclass,
|
||||
java::lang::ClassLoader *);
|
||||
|
||||
extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
|
||||
__attribute__((__malloc__));
|
||||
|
||||
|
@ -86,6 +86,7 @@ private:
|
||||
void checkInitialized();
|
||||
public: // actually package-private
|
||||
::java::util::HashMap * __attribute__((aligned(__alignof__( ::java::lang::Object)))) loadedClasses;
|
||||
::java::util::HashMap * loadingConstraints;
|
||||
::java::util::HashMap * definedPackages;
|
||||
private:
|
||||
::java::lang::ClassLoader * parent;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ClassLoader.java -- responsible for loading classes into the VM
|
||||
Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -45,6 +45,7 @@ import gnu.java.util.EmptyEnumeration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.CodeSource;
|
||||
@ -129,6 +130,15 @@ public abstract class ClassLoader
|
||||
*/
|
||||
final HashMap loadedClasses = new HashMap();
|
||||
|
||||
/**
|
||||
* Loading constraints registered with this classloader. This maps
|
||||
* a class name to a weak reference to a class. When the reference
|
||||
* is non-null, it means that a reference to the name must resolve
|
||||
* to the indicated class.
|
||||
*/
|
||||
final HashMap<String, WeakReference<Class>> loadingConstraints
|
||||
= new HashMap<String, WeakReference<Class>>();
|
||||
|
||||
/**
|
||||
* All packages defined by this classloader. It is not private in order to
|
||||
* allow native code (and trusted subclasses) access to this field.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
|
||||
|
||||
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
|
||||
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@ -41,6 +41,7 @@ details. */
|
||||
#include <java/lang/StringBuffer.h>
|
||||
#include <java/io/Serializable.h>
|
||||
#include <java/lang/Cloneable.h>
|
||||
#include <java/lang/ref/WeakReference.h>
|
||||
#include <java/util/HashMap.h>
|
||||
#include <gnu/gcj/runtime/BootClassLoader.h>
|
||||
#include <gnu/gcj/runtime/SystemClassLoader.h>
|
||||
@ -143,7 +144,21 @@ _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
|
||||
// them later.
|
||||
return;
|
||||
}
|
||||
loader->loadedClasses->put(klass->name->toString(), klass);
|
||||
|
||||
JvSynchronize sync (loader->loadingConstraints);
|
||||
|
||||
using namespace java::lang::ref;
|
||||
|
||||
jstring name = klass->getName();
|
||||
WeakReference *ref = (WeakReference *) loader->loadingConstraints->get (name);
|
||||
if (ref)
|
||||
{
|
||||
jclass constraint = (jclass) ref->get();
|
||||
if (constraint && constraint != klass)
|
||||
throw new java::lang::LinkageError(JvNewStringLatin1("loading constraint violated"));
|
||||
}
|
||||
loader->loadingConstraints->put(name, new WeakReference(klass));
|
||||
loader->loadedClasses->put(name, klass);
|
||||
}
|
||||
|
||||
// If we found an error while defining an interpreted class, we must
|
||||
@ -156,6 +171,46 @@ _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
|
||||
loader->loadedClasses->remove(klass->name->toString());
|
||||
}
|
||||
|
||||
// Check a loading constraint. In particular check that, if there is
|
||||
// a constraint for the name of KLASS in LOADER, that it maps to
|
||||
// KLASS. If there is no such constraint, make a new one. If the
|
||||
// constraint is violated, throw an exception. Do nothing for
|
||||
// primitive types.
|
||||
void
|
||||
_Jv_CheckOrCreateLoadingConstraint (jclass klass,
|
||||
java::lang::ClassLoader *loader)
|
||||
{
|
||||
// Strip arrays.
|
||||
while (klass->isArray())
|
||||
klass = klass->getComponentType();
|
||||
// Ignore primitive types.
|
||||
if (klass->isPrimitive())
|
||||
return;
|
||||
|
||||
if (! loader)
|
||||
loader = java::lang::VMClassLoader::bootLoader;
|
||||
jstring name = klass->getName();
|
||||
|
||||
JvSynchronize sync (loader->loadingConstraints);
|
||||
|
||||
using namespace java::lang::ref;
|
||||
|
||||
WeakReference *ref = (WeakReference *) loader->loadingConstraints->get (name);
|
||||
if (ref)
|
||||
{
|
||||
jclass constraint = (jclass) ref->get();
|
||||
if (constraint)
|
||||
{
|
||||
if (klass != constraint)
|
||||
throw new java::lang::LinkageError(JvNewStringLatin1("loading constraint violated"));
|
||||
// Otherwise, all is ok.
|
||||
return;
|
||||
}
|
||||
}
|
||||
// No constraint (or old constraint GC'd). Make a new one.
|
||||
loader->loadingConstraints->put(name, new WeakReference(klass));
|
||||
}
|
||||
|
||||
|
||||
// Class registration.
|
||||
//
|
||||
|
@ -246,13 +246,9 @@ _Jv_Linker::find_field (jclass klass, jclass owner,
|
||||
if (_Jv_CheckAccess (klass, *found_class, the_field->flags))
|
||||
{
|
||||
// Note that the field returned by find_field_helper is always
|
||||
// resolved. There's no point checking class loaders here,
|
||||
// since we already did the work to look up all the types.
|
||||
// FIXME: being lazy here would be nice.
|
||||
if (the_field->type != field_type)
|
||||
throw new java::lang::LinkageError
|
||||
(JvNewStringLatin1
|
||||
("field type mismatch with different loaders"));
|
||||
// resolved. However, we still use the constraint mechanism
|
||||
// because this may affect other lookups.
|
||||
_Jv_CheckOrCreateLoadingConstraint (klass, (*found_class)->loader);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -269,6 +265,23 @@ _Jv_Linker::find_field (jclass klass, jclass owner,
|
||||
return the_field;
|
||||
}
|
||||
|
||||
// Check loading constraints for method.
|
||||
void
|
||||
_Jv_Linker::check_loading_constraints (_Jv_Method *method, jclass self_class,
|
||||
jclass other_class)
|
||||
{
|
||||
JArray<jclass> *klass_args;
|
||||
jclass klass_return;
|
||||
|
||||
_Jv_GetTypesFromSignature (method, self_class, &klass_args, &klass_return);
|
||||
jclass *klass_arg = elements (klass_args);
|
||||
java::lang::ClassLoader *found_loader = other_class->loader;
|
||||
|
||||
_Jv_CheckOrCreateLoadingConstraint (klass_return, found_loader);
|
||||
for (int i = 0; i < klass_args->length; i++)
|
||||
_Jv_CheckOrCreateLoadingConstraint (*(klass_arg++), found_loader);
|
||||
}
|
||||
|
||||
_Jv_Method *
|
||||
_Jv_Linker::resolve_method_entry (jclass klass, jclass &found_class,
|
||||
int class_index, int name_and_type_index,
|
||||
@ -359,39 +372,10 @@ _Jv_Linker::resolve_method_entry (jclass klass, jclass &found_class,
|
||||
throw new java::lang::NoSuchMethodError (sb->toString());
|
||||
}
|
||||
|
||||
// if (found_class->loader != klass->loader), then we
|
||||
// must actually check that the types of arguments
|
||||
// correspond. That is, for each argument type, and
|
||||
// the return type, doing _Jv_FindClassFromSignature
|
||||
// with either loader should produce the same result,
|
||||
// i.e., exactly the same jclass object. JVMS 5.4.3.3
|
||||
// if (found_class->loader != klass->loader), then we must actually
|
||||
// check that the types of arguments correspond. JVMS 5.4.3.3.
|
||||
if (found_class->loader != klass->loader)
|
||||
{
|
||||
JArray<jclass> *found_args, *klass_args;
|
||||
jclass found_return, klass_return;
|
||||
|
||||
_Jv_GetTypesFromSignature (the_method,
|
||||
found_class,
|
||||
&found_args,
|
||||
&found_return);
|
||||
_Jv_GetTypesFromSignature (the_method,
|
||||
klass,
|
||||
&klass_args,
|
||||
&klass_return);
|
||||
|
||||
jclass *found_arg = elements (found_args);
|
||||
jclass *klass_arg = elements (klass_args);
|
||||
|
||||
for (int i = 0; i < found_args->length; i++)
|
||||
{
|
||||
if (*(found_arg++) != *(klass_arg++))
|
||||
throw new java::lang::LinkageError (JvNewStringLatin1
|
||||
("argument type mismatch with different loaders"));
|
||||
}
|
||||
if (found_return != klass_return)
|
||||
throw new java::lang::LinkageError (JvNewStringLatin1
|
||||
("return type mismatch with different loaders"));
|
||||
}
|
||||
check_loading_constraints (the_method, klass, found_class);
|
||||
|
||||
return the_method;
|
||||
}
|
||||
@ -925,7 +909,8 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
|
||||
continue;
|
||||
|
||||
meth = NULL;
|
||||
for (jclass cl = klass; cl; cl = cl->getSuperclass())
|
||||
jclass cl;
|
||||
for (cl = klass; cl; cl = cl->getSuperclass())
|
||||
{
|
||||
meth = _Jv_GetMethodLocal (cl, iface->methods[j].name,
|
||||
iface->methods[j].signature);
|
||||
@ -947,6 +932,9 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
|
||||
itable[pos] = (void *) &_Jv_ThrowAbstractMethodError;
|
||||
else
|
||||
itable[pos] = meth->ncode;
|
||||
|
||||
if (cl->loader != iface->loader)
|
||||
check_loading_constraints (meth, cl, iface);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1501,6 +1489,11 @@ _Jv_Linker::layout_vtable_methods (jclass klass)
|
||||
sb->append(_Jv_GetMethodString(declarer, super_meth));
|
||||
throw new VerifyError(sb->toString());
|
||||
}
|
||||
else if (declarer->loader != klass->loader)
|
||||
{
|
||||
// JVMS 5.4.2.
|
||||
check_loading_constraints (meth, klass, declarer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user