/** * Gets the bytecode of a native code replacement method. * * @param method * @param cl * @return the bytecode */ private static VmByteCode getNativeCodeReplacement( VmMethod method, VmClassLoader cl, boolean verbose) { final String className = method.getDeclaringClass().getName(); final String nativeClassName = VmUtils.getNativeClassName(className); final VmType nativeType; try { nativeType = cl.loadClass(nativeClassName, false); } catch (ClassNotFoundException ex) { if (verbose) { BootLogInstance.get().error("Native class replacement (" + nativeClassName + ") not found"); } return null; } String signature = method.getSignature(); if (!method.isStatic()) { signature = '(' + Signature.toSignature(method.getDeclaringClass()) + signature.substring(1); } final VmMethod nativeMethod = nativeType.getNativeMethodReplacement(method.getName(), signature); if (nativeMethod == null) { if (verbose) { BootLogInstance.get().error("Native method replacement (" + method + ") not found"); } return null; } if (!nativeMethod.isStatic()) { throw new ClassFormatError("Native method replacement must be static"); } return nativeMethod.getBytecode(); }
private final void loadExtension(Extension ext) { final String id = ext.getDeclaringPluginDescriptor().getId(); final URL url; try { // note: ".../-" match everything starting with "plugin:" + id + "!/" url = new URL("plugin:" + id + "!/-"); final ClassLoader cl = ext.getDeclaringPluginDescriptor().getPluginClassLoader(); final CodeSource cs = new CodeSource(url, (Certificate[]) null); final Permissions perms = new Permissions(); codeSource2Permissions.put(cs, perms); // BootLogInstance.get().debug("Adding permissions for " + cs); final ConfigurationElement[] elems = ext.getConfigurationElements(); final int count = elems.length; for (int i = 0; i < count; i++) { final ConfigurationElement elem = elems[i]; final String type = elem.getAttribute("class"); final String name = elem.getAttribute("name"); final String actions = elem.getAttribute("actions"); if (type != null) { final Object perm; try { final Class permClass = cl.loadClass(type); if ((name != null) && (actions != null)) { final Constructor c = permClass.getConstructor(NAME_ACTIONS_ARGS); perm = c.newInstance(new Object[] {name, actions}); } else if (name != null) { final Constructor c = permClass.getConstructor(NAME_ARGS); perm = c.newInstance(new Object[] {name}); } else { perm = permClass.newInstance(); } final Permission p = (Permission) perm; perms.add(p); } catch (ClassNotFoundException ex) { BootLogInstance.get().error("Permission class " + type + " not found"); } catch (InstantiationException ex) { BootLogInstance.get().error("Cannot instantiate permission class " + type); } catch (IllegalAccessException ex) { BootLogInstance.get().error("Illegal access to permission class " + type); } catch (NoSuchMethodException ex) { BootLogInstance.get() .error("Constructor not found on permission class " + type + " in plugin " + id); } catch (InvocationTargetException ex) { BootLogInstance.get().error("Error constructing permission class " + type, ex); } catch (ClassCastException ex) { BootLogInstance.get().error("Permission class " + type + " not instance of Permission"); } } } } catch (MalformedURLException ex) { BootLogInstance.get().error("Cannot create plugin codesource", ex); } }
/** * Decode a given class. * * @param data * @param rejectNatives * @param clc * @param protectionDomain * @return The decoded class * @throws ClassFormatError */ private static final VmType decodeClass( ByteBuffer data, boolean rejectNatives, VmClassLoader clc, ProtectionDomain protectionDomain) throws ClassFormatError { final VmSharedStatics sharedStatics = clc.getSharedStatics(); final VmIsolatedStatics isolatedStatics = clc.getIsolatedStatics(); final int slotSize = clc.getArchitecture().getReferenceSize(); final int magic = data.getInt(); if (magic != 0xCAFEBABE) { throw new ClassFormatError("invalid magic"); } final int min_version = data.getChar(); final int maj_version = data.getChar(); if (false) { BootLogInstance.get().debug("Class file version " + maj_version + ';' + min_version); } final int cpcount = data.getChar(); // allocate enough space for the CP final byte[] tags = new byte[cpcount]; final VmCP cp = new VmCP(cpcount); for (int i = 1; i < cpcount; i++) { final int tag = data.get() & 0xFF; tags[i] = (byte) tag; switch (tag) { case 1: // Utf8 cp.setUTF8(i, readUTF(data)); break; case 3: // int cp.setInt(i, data.getInt()); break; case 4: // float // cp.setInt(i, data.getInt()); final int ival = data.getInt(); final float fval = Float.intBitsToFloat(ival); cp.setFloat(i, fval); break; case 5: // long cp.setLong(i, data.getLong()); i++; break; case 6: // double // cp.setLong(i, data.getLong()); final long lval = data.getLong(); final double dval = Double.longBitsToDouble(lval); cp.setDouble(i, dval); i++; break; case 7: // class cp.setInt(i, data.getChar()); break; case 8: // String cp.setInt(i, data.getChar()); break; case 9: // Fieldref case 10: // Methodref case 11: // IMethodref { final int clsIdx = data.getChar(); final int ntIdx = data.getChar(); cp.setInt(i, clsIdx << 16 | ntIdx); break; } case 12: // Name and Type { final int nIdx = data.getChar(); final int dIdx = data.getChar(); cp.setInt(i, nIdx << 16 | dIdx); break; } default: throw new ClassFormatError("Invalid constantpool tag: " + tags[i]); } } // Now patch the required entries (level 1) for (int i = 1; i < cpcount; i++) { switch (tags[i]) { case 7: { // Class final int idx = cp.getInt(i); final VmConstClass constClass = new VmConstClass(cp.getUTF8(idx)); cp.setConstClass(i, constClass); break; } case 8: { // String final int idx = cp.getInt(i); final int staticsIdx = sharedStatics.allocConstantStringField(cp.getUTF8(idx)); final VmConstString constStr = new VmConstString(staticsIdx); cp.setString(i, constStr); break; } } } // Now patch the required entries (level 2) for (int i = 1; i < cpcount; i++) { final int tag = tags[i]; if ((tag >= 9) && (tag <= 11)) { final int v = cp.getInt(i); final VmConstClass constClass = cp.getConstClass(v >>> 16); final int nat = cp.getInt(v & 0xFFFF); final String name = cp.getUTF8(nat >>> 16); final String descriptor = cp.getUTF8(nat & 0xFFFF); switch (tag) { case 9: // FieldRef cp.setConstFieldRef(i, new VmConstFieldRef(constClass, name, descriptor)); break; case 10: // MethodRef cp.setConstMethodRef(i, new VmConstMethodRef(constClass, name, descriptor)); break; case 11: // IMethodRef cp.setConstIMethodRef(i, new VmConstIMethodRef(constClass, name, descriptor)); break; } } } // Cleanup the unwantend entries for (int i = 1; i < cpcount; i++) { switch (tags[i]) { case 12: // Name and Type cp.reset(i); break; } } final int classModifiers = data.getChar(); final VmConstClass this_class = cp.getConstClass(data.getChar()); final String clsName = this_class.getClassName(); final VmConstClass super_class = cp.getConstClass(data.getChar()); final String superClassName; if (super_class != null) { superClassName = super_class.getClassName(); } else { superClassName = null; } // Allocate the class object final VmType cls; if (Modifier.isInterface(classModifiers)) { cls = new VmInterfaceClass(clsName, superClassName, clc, classModifiers, protectionDomain); } else { cls = new VmNormalClass(clsName, superClassName, clc, classModifiers, protectionDomain); } cls.setCp(cp); // Determine if we can safely align the fields // int pragmaFlags = 0; if (isBootType(cls)) { cls.addPragmaFlags(TypePragmaFlags.NO_FIELD_ALIGNMENT); } cls.addPragmaFlags(getClassNamePragmaFlags(clsName)); // Interface table cls.addPragmaFlags(readInterfaces(data, cls, cp)); // Field table final FieldData[] fieldData = readFields(data, cp, slotSize, clc); // Method Table readMethods(data, rejectNatives, cls, cp, sharedStatics, clc); // Read class attributes final int acount = data.getChar(); VmAnnotation[] rVisAnn = null; VmAnnotation[] rInvisAnn = null; String sourceFile = null; String signature = null; for (int a = 0; a < acount; a++) { final String attrName = cp.getUTF8(data.getChar()); final int length = data.getInt(); if (VmArray.equals(RuntimeVisibleAnnotationsAttrName, attrName)) { byte[] buf = new byte[length]; data.slice().get(buf); cls.setRawAnnotations(buf); rVisAnn = readRuntimeAnnotations(data, cp, true, clc); } else if (VmArray.equals(RuntimeInvisibleAnnotationsAttrName, attrName)) { rInvisAnn = readRuntimeAnnotations(data, cp, false, clc); } else if (VmArray.equals(SourceFileAttrName, attrName)) { sourceFile = cp.getUTF8(data.getChar()); } else if (VmArray.equals(SignatureAttrName, attrName)) { signature = cp.getUTF8(data.getChar()); } else { skip(data, length); } } cls.setRuntimeAnnotations(rVisAnn); cls.setSourceFile(sourceFile); cls.setSignature(signature); if (rInvisAnn != null) { cls.addPragmaFlags(getClassPragmaFlags(rInvisAnn, clsName)); } if (rVisAnn != null) { cls.addPragmaFlags(getClassPragmaFlags(rVisAnn, clsName)); } // Create the fields if (fieldData != null) { createFields(cls, fieldData, sharedStatics, isolatedStatics, slotSize, cls.getPragmaFlags()); } return cls; }
protected void doSetOption(int option_id, Object val) throws SocketException { BootLogInstance.get().error("Unknown option " + option_id); }