From e6b512b8180176104b22dfbd2eb23aefab7b49d6 Mon Sep 17 00:00:00 2001 From: rtrimana Date: Thu, 27 Jun 2019 12:42:35 -0700 Subject: [PATCH] Fixing the ClassLoader.defineClass() method issue that could not find the necessary class because JPF did not do recursive look-up for ClassLoaderInfo.loadClass(). --- examples/ClassDemo.java | 5 +++ examples/SunClassLoader.java | 38 +++++++++++++++++++ src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java | 7 +++- .../jpf/vm/JPF_java_lang_ClassLoader.java | 3 +- 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 examples/SunClassLoader.java diff --git a/examples/ClassDemo.java b/examples/ClassDemo.java index 0a76996..d0e10a1 100644 --- a/examples/ClassDemo.java +++ b/examples/ClassDemo.java @@ -2,10 +2,15 @@ import java.lang.*; import java.lang.reflect.*; import java.util.*; import java.math.*; +import java.lang.ClassLoader; public class ClassDemo { public static void main(String[] args) throws Exception { + + ClassLoader cl = new ClassLoader(); + byte[] bytes = new byte[150]; + Class cls = cl.defineClass("sun.reflect.MagicAccessorImpl", bytes, 0, bytes.length); // returns an array of TypeVariable object TypeVariable[] tValue = List.class.getTypeParameters(); diff --git a/examples/SunClassLoader.java b/examples/SunClassLoader.java new file mode 100644 index 0000000..195c3a6 --- /dev/null +++ b/examples/SunClassLoader.java @@ -0,0 +1,38 @@ +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; + +import java.util.Map; +import java.util.HashMap; + +/** + * Special class loader, which when running on Sun VM allows to generate accessor classes for any method + */ +public class SunClassLoader extends ClassLoader implements Opcodes { + private void loadMagic() { + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); + cw.visit(Opcodes.V1_4, Opcodes.ACC_PUBLIC, "sun/reflect/GroovyMagic", null, "sun/reflect/MagicAccessorImpl", null); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "sun/reflect/MagicAccessorImpl", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(0,0); + mv.visitEnd(); + cw.visitEnd(); + + define(cw.toByteArray(), "sun.reflect.GroovyMagic"); + } + + protected void define(byte[] bytes, final String name) { + //knownClasses.put(name, defineClass(name, bytes, 0, bytes.length)); + Class cls = defineClass(name, bytes, 0, bytes.length); + } + + protected final Map knownClasses = new HashMap(); + + public static void main(String[] args) { + SunClassLoader sun = new SunClassLoader(); + sun.loadMagic(); + } +} diff --git a/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java b/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java index 07fbf5f..dec2423 100644 --- a/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java +++ b/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java @@ -585,7 +585,12 @@ public class ClassLoaderInfo } } } - + // TODO: Fix for Groovy's model-checking + // TODO: May need to do a recursive lookup + if (parent != null) { + return parent.loadClass(typeName); + } + // initiate the roundtrip & bail out pushloadClassFrame(typeName); throw new LoadOnJPFRequired(typeName); diff --git a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java index 4fd6a25..136c12e 100644 --- a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java +++ b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java @@ -144,9 +144,10 @@ public class JPF_java_lang_ClassLoader extends NativePeer { byte[] buffer = env.getByteArrayObject(bufferRef); try { + ClassInfo ci = cl.getResolvedClassInfo( cname, buffer, offset, length); - // Note: if the representation is not of a supported major or minor version, loading + // Note: if the representation is not of a supported major or minor version, loading // throws an UnsupportedClassVersionError. But for now, we do not check for this here // since we don't do much with minor and major versions -- 2.34.1