diff options
author | jfrijters <jfrijters> | 2013-08-12 11:55:55 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2013-08-12 11:55:55 +0400 |
commit | 5befcded8aa819499e9033140f628c306d436e5f (patch) | |
tree | b220f4fca974842f1835c33a5defa82992ec5606 | |
parent | a800686029a45aad051c4a59d6d00633de8e7c79 (diff) |
Switched from @HasCallerID to @CallerSensitive and merged CallerSenstive related 7u40 changes.
-rw-r--r-- | classpath/ikvm/internal/HasCallerID.java | 36 | ||||
-rw-r--r-- | ikvmc/CompilerClassLoader.cs | 285 | ||||
-rw-r--r-- | openjdk/allsources.lst | 24 | ||||
-rw-r--r-- | openjdk/java/io/ObjectStreamClass.java | 20 | ||||
-rw-r--r-- | openjdk/java/lang/Class.java | 181 | ||||
-rw-r--r-- | openjdk/java/lang/ClassLoader.java | 57 | ||||
-rw-r--r-- | openjdk/java/lang/System.java | 11 | ||||
-rw-r--r-- | openjdk/java/lang/Thread.java | 37 | ||||
-rw-r--r-- | openjdk/java/lang/invoke/MethodHandles.java | 14 | ||||
-rw-r--r-- | openjdk/java/lang/reflect/Constructor.java | 6 | ||||
-rw-r--r-- | openjdk/java/lang/reflect/Field.java | 186 | ||||
-rw-r--r-- | openjdk/java/lang/reflect/Method.java | 6 | ||||
-rw-r--r-- | openjdk/java/security/AccessController.java | 48 | ||||
-rw-r--r-- | openjdk/java/sql/DriverManager.java | 78 | ||||
-rw-r--r-- | openjdk/java/util/ResourceBundle.java | 29 | ||||
-rw-r--r-- | openjdk/response.txt | 41 | ||||
-rw-r--r-- | openjdk/sun/misc/Unsafe.java | 2 | ||||
-rw-r--r-- | openjdk/sun/reflect/Reflection.java | 9 | ||||
-rw-r--r-- | runtime/ClassFile.cs | 22 | ||||
-rw-r--r-- | runtime/DynamicTypeWrapper.cs | 72 | ||||
-rw-r--r-- | runtime/intrinsics.cs | 60 |
21 files changed, 742 insertions, 482 deletions
diff --git a/classpath/ikvm/internal/HasCallerID.java b/classpath/ikvm/internal/HasCallerID.java deleted file mode 100644 index 27b1a177..00000000 --- a/classpath/ikvm/internal/HasCallerID.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -package ikvm.internal; - -import java.lang.annotation.*; - -/* This annotation is used to mark method inside the core class library that require an additional (hidden) ikvm.internal.CallerID parameter - * (automatically supplied by the runtime) to efficiently query the caller's class or class loader. - * It should only be applied to final or static methods that use one of the supported caller id methods (as defined in intrinsics.cs) - */ - -@Retention(RetentionPolicy.CLASS) -@Target({ ElementType.METHOD }) -@ikvm.lang.Internal -public @interface HasCallerID { } diff --git a/ikvmc/CompilerClassLoader.cs b/ikvmc/CompilerClassLoader.cs index 5f8d1d5b..e7247c17 100644 --- a/ikvmc/CompilerClassLoader.cs +++ b/ikvmc/CompilerClassLoader.cs @@ -44,7 +44,7 @@ namespace IKVM.Internal { sealed class CompilerClassLoader : ClassLoaderWrapper { - private Dictionary<string, JarItemReference> classes; + private Dictionary<string, Jar.Item> classes; private Dictionary<string, RemapperTypeWrapper> remapped = new Dictionary<string, RemapperTypeWrapper>(); private string assemblyName; private string assemblyFile; @@ -63,7 +63,6 @@ namespace IKVM.Internal private Dictionary<MethodKey, IKVM.Internal.MapXml.InstructionList> mapxml_MethodBodies; private Dictionary<MethodKey, IKVM.Internal.MapXml.ReplaceMethodCall[]> mapxml_ReplacedMethods; private Dictionary<MethodKey, IKVM.Internal.MapXml.InstructionList> mapxml_MethodPrologues; - private Dictionary<string, string> baseClasses; private IKVM.Internal.MapXml.Root map; private List<object> assemblyAnnotations; private List<string> classesToCompile; @@ -74,7 +73,7 @@ namespace IKVM.Internal private List<string> jarList = new List<string>(); private List<TypeWrapper> allwrappers; - internal CompilerClassLoader(AssemblyClassLoader[] referencedAssemblies, CompilerOptions options, FileInfo assemblyPath, bool targetIsModule, string assemblyName, Dictionary<string, JarItemReference> classes) + internal CompilerClassLoader(AssemblyClassLoader[] referencedAssemblies, CompilerOptions options, FileInfo assemblyPath, bool targetIsModule, string assemblyName, Dictionary<string, Jar.Item> classes) : base(options.codegenoptions, null) { this.referencedAssemblies = referencedAssemblies; @@ -99,10 +98,7 @@ namespace IKVM.Internal internal void AddReference(AssemblyClassLoader acl) { - AssemblyClassLoader[] temp = new AssemblyClassLoader[referencedAssemblies.Length + 1]; - Array.Copy(referencedAssemblies, 0, temp, 0, referencedAssemblies.Length); - temp[temp.Length - 1] = acl; - referencedAssemblies = temp; + referencedAssemblies = ArrayUtil.Concat(referencedAssemblies, acl); } internal void AddReference(CompilerClassLoader ccl) @@ -172,7 +168,10 @@ namespace IKVM.Internal string mainAssemblyName = options.sharedclassloader != null && options.sharedclassloader[0] != this ? options.sharedclassloader[0].assemblyName : assemblyName; - AttributeHelper.SetInternalsVisibleToAttribute(assemblyBuilder, mainAssemblyName + DynamicClassLoader.DynamicAssemblySuffixAndPublicKey); + if(!DisableDynamicBinding) + { + AttributeHelper.SetInternalsVisibleToAttribute(assemblyBuilder, mainAssemblyName + DynamicClassLoader.DynamicAssemblySuffixAndPublicKey); + } return moduleBuilder; } @@ -272,11 +271,10 @@ namespace IKVM.Internal } else { - JarItemReference itemRef; + Jar.Item itemRef; if(classes.TryGetValue(name, out itemRef)) { classes.Remove(name); - JarItem classdef = itemRef.Jar.Items[itemRef.Index]; ClassFile f; try { @@ -285,7 +283,8 @@ namespace IKVM.Internal { cfp |= ClassFileParseOptions.LineNumberTable; } - f = new ClassFile(classdef.data, 0, classdef.data.Length, name, cfp); + byte[] buf = itemRef.GetData(); + f = new ClassFile(buf, 0, buf.Length, name, cfp); } catch(ClassFormatError x) { @@ -330,22 +329,12 @@ namespace IKVM.Internal f.SetInternal(); } } - if(!f.IsInterface - && !f.IsAbstract - && !f.IsPublic - && !f.IsInternal - && !f.IsFinal - && !baseClasses.ContainsKey(f.Name) - && !options.targetIsModule - && options.sharedclassloader == null) - { - f.SetEffectivelyFinal(); - } if(f.SourceFileAttribute != null) { - if(classdef.path != null) + FileInfo path = itemRef.Path; + if(path != null) { - string sourceFile = Path.GetFullPath(Path.Combine(classdef.path.DirectoryName, f.SourceFileAttribute)); + string sourceFile = Path.GetFullPath(Path.Combine(path.DirectoryName, f.SourceFileAttribute)); if(File.Exists(sourceFile)) { f.SourcePath = sourceFile; @@ -370,9 +359,14 @@ namespace IKVM.Internal { TypeWrapper tw = DefineClass(f, null); // we successfully created the type, so we don't need to include the class as a resource - itemRef.Jar.Items[itemRef.Index] = options.nojarstubs - ? new JarItem() // null entry - : new JarItem(itemRef.Jar.Items[itemRef.Index].zipEntry, null, null); // create a stub class pseudo resource + if (options.nojarstubs) + { + itemRef.Remove(); + } + else + { + itemRef.MarkAsStub(); + } return tw; } catch (ClassFormatError x) @@ -687,11 +681,11 @@ namespace IKVM.Internal ccl.AddWildcardExports(exportedNamesPerAssembly); foreach (Jar jar in ccl.options.jars) { - foreach (JarItem item in jar.Items) + foreach (Jar.Item item in jar) { - if (item.zipEntry != null && item.data != null) + if (!item.IsStub) { - AddExportMapEntry(exportedNamesPerAssembly, ccl, item.zipEntry.Name); + AddExportMapEntry(exportedNamesPerAssembly, ccl, item.Name); } } } @@ -749,34 +743,25 @@ namespace IKVM.Internal } zip.SetLevel(9); List<string> stubs = new List<string>(); - foreach (JarItem item in options.jars[i].Items) + foreach (Jar.Item item in options.jars[i]) { - if (item.zipEntry == null) - { - continue; - } - if (item.data == null) + if (item.IsStub) { // we don't want stub class pseudo resources for classes loaded from the file system if (i != options.classesJar) { - stubs.Add(item.zipEntry.Name); + stubs.Add(item.Name); } continue; } - ZipEntry zipEntry = new ZipEntry(item.zipEntry.Name); - zipEntry.Comment = item.zipEntry.Comment; - zipEntry.CompressionMethod = item.zipEntry.CompressionMethod; - zipEntry.DosTime = item.zipEntry.DosTime; - zipEntry.ExternalFileAttributes = item.zipEntry.ExternalFileAttributes; - zipEntry.ExtraData = item.zipEntry.ExtraData; - zipEntry.Flags = item.zipEntry.Flags; + ZipEntry zipEntry = item.ZipEntry; if (options.compressedResources || zipEntry.CompressionMethod != CompressionMethod.Stored) { zipEntry.CompressionMethod = CompressionMethod.Deflated; } zip.PutNextEntry(zipEntry); - zip.Write(item.data, 0, item.data.Length); + byte[] data = item.GetData(); + zip.Write(data, 0, data.Length); zip.CloseEntry(); hasEntries = true; } @@ -1293,10 +1278,7 @@ namespace IKVM.Internal if(specialCases != null) { CodeEmitter ilgen; - Type[] temp = typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig); - Type[] argTypes = new Type[temp.Length + 1]; - temp.CopyTo(argTypes, 1); - argTypes[0] = typeWrapper.shadowType; + Type[] argTypes = ArrayUtil.Concat(typeWrapper.shadowType, typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig)); if(typeWrapper.helperTypeBuilder == null) { typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType("__Helper", TypeAttributes.NestedPublic | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract); @@ -1434,10 +1416,7 @@ namespace IKVM.Internal attr &= ~MethodAttributes.MemberAccessMask; attr |= MethodAttributes.Assembly; } - Type[] exParamTypes = new Type[paramTypes.Length + 1]; - Array.Copy(paramTypes, 0, exParamTypes, 1, paramTypes.Length); - exParamTypes[0] = typeWrapper.shadowType; - mbHelper = typeWrapper.typeBuilder.DefineMethod("instancehelper_" + m.Name, attr, CallingConventions.Standard, retType, exParamTypes); + mbHelper = typeWrapper.typeBuilder.DefineMethod("instancehelper_" + m.Name, attr, CallingConventions.Standard, retType, ArrayUtil.Concat(typeWrapper.shadowType, paramTypes)); if(m.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute custattr in m.Attributes) @@ -1689,10 +1668,8 @@ namespace IKVM.Internal if(m.nonvirtualAlternateBody != null || (m.@override != null && overriders.Count > 0)) { RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType; - Type[] argTypes = new Type[paramTypes.Length + 1]; - argTypes[0] = typeWrapper.TypeAsSignatureType; - this.GetParametersForDefineMethod().CopyTo(argTypes, 1); - MethodBuilder mb = typeWrapper.typeBuilder.DefineMethod("nonvirtualhelper/" + this.Name, MethodAttributes.Private | MethodAttributes.Static, this.ReturnTypeForDefineMethod, argTypes); + MethodBuilder mb = typeWrapper.typeBuilder.DefineMethod("nonvirtualhelper/" + this.Name, MethodAttributes.Private | MethodAttributes.Static, + ReturnTypeForDefineMethod, ArrayUtil.Concat(typeWrapper.TypeAsSignatureType, GetParametersForDefineMethod())); if(m.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute custattr in m.Attributes) @@ -2734,13 +2711,13 @@ namespace IKVM.Internal List<object> assemblyAnnotations = new List<object>(); Tracer.Info(Tracer.Compiler, "Parsing class files"); // map the class names to jar entries - Dictionary<string, JarItemReference> h = new Dictionary<string, JarItemReference>(); + Dictionary<string, Jar.Item> h = new Dictionary<string, Jar.Item>(); List<string> classNames = new List<string>(); foreach (Jar jar in options.jars) { - for (int i = 0; i < jar.Items.Count; i++) + foreach (Jar.Item item in jar) { - string name = jar.Items[i].zipEntry.Name; + string name = item.Name; if (name.EndsWith(".class", StringComparison.Ordinal) && name.Length > 6 && name.IndexOf('.') == name.Length - 6) @@ -2749,14 +2726,14 @@ namespace IKVM.Internal if (options.IsExcludedClass(className)) { // we don't compile the class and we also don't include it as a resource - jar.Items[i] = new JarItem(); + item.Remove(); } else { if (h.ContainsKey(className)) { StaticCompiler.IssueMessage(Message.DuplicateClassName, className); - JarItemReference itemRef = h[className]; + Jar.Item itemRef = h[className]; if ((options.classesJar != -1 && itemRef.Jar == options.jars[options.classesJar]) || jar != itemRef.Jar) { // the previous class stays, because it was either in an earlier jar or we're processing the classes.jar @@ -2770,52 +2747,59 @@ namespace IKVM.Internal classNames.Remove(className); } } - h.Add(className, new JarItemReference(jar, i)); + h.Add(className, item); classNames.Add(className); } } } } - // now process all the classes to record the classes that are used as base classes and - // to look for assembly attribute annotations and the main method - Dictionary<string, string> baseClasses = new Dictionary<string, string>(); - foreach (string className in classNames) + + // look for "assembly" type that acts as a placeholder for assembly attributes + Jar.Item assemblyType; + if (h.TryGetValue("assembly", out assemblyType)) { try { - JarItemReference itemRef = h[className]; - byte[] buf = itemRef.Jar.Items[itemRef.Index].data; + byte[] buf = assemblyType.GetData(); ClassFile f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None); - if (!f.IsInterface && f.SuperClass != null) - { - baseClasses[f.SuperClass] = f.SuperClass; - } // NOTE the "assembly" type in the unnamed package is a magic type // that acts as the placeholder for assembly attributes - if (className == f.Name && f.Name == "assembly" && f.Annotations != null) + if (f.Name == "assembly" && f.Annotations != null) { assemblyAnnotations.AddRange(f.Annotations); // HACK remove "assembly" type that exists only as a placeholder for assembly attributes h.Remove(f.Name); - itemRef.Jar.Items[itemRef.Index] = new JarItem(); - continue; + assemblyType.Remove(); } - if (options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll)) + } + catch (ClassFormatError) { } + } + + // now look for a main method + if (options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll)) + { + foreach (string className in classNames) + { + try { - foreach (ClassFile.Method m in f.Methods) + byte[] buf = h[className].GetData(); + ClassFile f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None); + if (f.Name == className) { - if (m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") + foreach (ClassFile.Method m in f.Methods) { - StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name); - options.mainClass = f.Name; - break; + if (m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") + { + StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name); + options.mainClass = f.Name; + goto break_outer; + } } } } + catch (ClassFormatError) { } } - catch (ClassFormatError) - { - } + break_outer: ; } if(options.guessFileKind && options.mainClass == null) @@ -2880,7 +2864,6 @@ namespace IKVM.Internal referencedAssemblies[i] = acl; } loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h); - loader.baseClasses = baseClasses; loader.assemblyAnnotations = assemblyAnnotations; loader.classesToCompile = new List<string>(h.Keys); if(options.remapfile != null) @@ -3333,7 +3316,7 @@ namespace IKVM.Internal { internal readonly string Name; internal readonly string Comment; - internal readonly List<JarItem> Items = new List<JarItem>(); + private readonly List<JarItem> Items = new List<JarItem>(); internal Jar(string name, string comment) { @@ -3359,31 +3342,111 @@ namespace IKVM.Internal zipEntry.CompressionMethod = CompressionMethod.Stored; Items.Add(new JarItem(zipEntry, data, fileInfo)); } - } - struct JarItem - { - internal readonly ZipEntry zipEntry; - internal readonly byte[] data; - internal readonly FileInfo path; // path of the original file, if it was individual file (used to construct source file path) + private struct JarItem + { + internal readonly ZipEntry zipEntry; + internal readonly byte[] data; + internal readonly FileInfo path; // path of the original file, if it was individual file (used to construct source file path) - internal JarItem(ZipEntry zipEntry, byte[] data, FileInfo path) + internal JarItem(ZipEntry zipEntry, byte[] data, FileInfo path) + { + this.zipEntry = zipEntry; + this.data = data; + this.path = path; + } + } + + public struct Item { - this.zipEntry = zipEntry; - this.data = data; - this.path = path; + internal readonly Jar Jar; + private readonly int Index; + + internal Item(Jar jar, int index) + { + this.Jar = jar; + this.Index = index; + } + + internal string Name + { + get { return Jar.Items[Index].zipEntry.Name; } + } + + internal byte[] GetData() + { + return Jar.Items[Index].data; + } + + internal FileInfo Path + { + get { return Jar.Items[Index].path; } + } + + internal ZipEntry ZipEntry + { + get + { + ZipEntry org = Jar.Items[Index].zipEntry; + ZipEntry zipEntry = new ZipEntry(org.Name); + zipEntry.Comment = org.Comment; + zipEntry.CompressionMethod = org.CompressionMethod; + zipEntry.DosTime = org.DosTime; + zipEntry.ExternalFileAttributes = org.ExternalFileAttributes; + zipEntry.ExtraData = org.ExtraData; + zipEntry.Flags = org.Flags; + return zipEntry; + } + } + + internal void Remove() + { + Jar.Items[Index] = new JarItem(); + } + + internal void MarkAsStub() + { + Jar.Items[Index] = new JarItem(Jar.Items[Index].zipEntry, null, null); + } + + internal bool IsStub + { + get { return Jar.Items[Index].data == null; } + } } - } - struct JarItemReference - { - internal readonly Jar Jar; - internal readonly int Index; + internal struct JarEnumerator + { + private readonly Jar jar; + private int index; + + internal JarEnumerator(Jar jar) + { + this.jar = jar; + this.index = -1; + } - internal JarItemReference(Jar jar, int index) + public Item Current + { + get { return new Item(jar, index); } + } + + public bool MoveNext() + { + while (index + 1 < jar.Items.Count) + { + if (jar.Items[++index].zipEntry != null) + { + return true; + } + } + return false; + } + } + + public JarEnumerator GetEnumerator() { - this.Jar = jar; - this.Index = index; + return new JarEnumerator(this); } } @@ -3572,6 +3635,7 @@ namespace IKVM.Internal UnableToResolveType = 133, StubsAreDeprecated = 134, WrongClassName = 135, + ReflectionCallerClassRequiresCallerID = 136, UnknownWarning = 999, // This is where the errors start StartErrors = 4000, @@ -3590,6 +3654,7 @@ namespace IKVM.Internal NonPrimaryAssemblyReference = 4013, MissingType = 4014, MissingReference = 4015, + CallerSensitiveOnUnsupportedMethod = 4016, // Fatal errors ResponseFileDepthExceeded = 5000, ErrorReadingFile = 5001, @@ -3651,7 +3716,7 @@ namespace IKVM.Internal static class StaticCompiler { - internal static readonly Universe Universe = new Universe(UniverseOptions.ResolveMissingMembers); + internal static readonly Universe Universe = new Universe(UniverseOptions.ResolveMissingMembers | UniverseOptions.EnableFunctionPointers); internal static Assembly runtimeAssembly; internal static Assembly runtimeJniAssembly; internal static CompilerOptions toplevel; @@ -3904,6 +3969,10 @@ namespace IKVM.Internal case Message.WrongClassName: msg = "Unable to compile \"{0}\" (wrong name: \"{1}\")"; break; + case Message.ReflectionCallerClassRequiresCallerID: + msg = "Reflection.getCallerClass() called from non-CallerID method" + Environment.NewLine + + " (\"{0}.{1}{2}\")"; + break; case Message.UnableToCreateProxy: msg = "Unable to create proxy \"{0}\"" + Environment.NewLine + " (\"{1}\")"; @@ -3944,6 +4013,10 @@ namespace IKVM.Internal case Message.UnknownWarning: msg = "{0}"; break; + case Message.CallerSensitiveOnUnsupportedMethod: + msg = "CallerSensitive annotation on unsupported method" + Environment.NewLine + + " (\"{0}.{1}{2}\")"; + break; default: throw new InvalidProgramException(); } diff --git a/openjdk/allsources.lst b/openjdk/allsources.lst index 5df16cb5..46f01df7 100644 --- a/openjdk/allsources.lst +++ b/openjdk/allsources.lst @@ -4,7 +4,6 @@ ../classpath/ikvm/internal/AssemblyClassLoader.java ../classpath/ikvm/internal/CallerID.java ../classpath/ikvm/internal/Formatter.java -../classpath/ikvm/internal/HasCallerID.java ../classpath/ikvm/internal/JMath.java ../classpath/ikvm/internal/MonoUtils.java ../classpath/ikvm/internal/Util.java @@ -67,6 +66,13 @@ java/awt/image/BandCombineOp.java java/awt/image/BufferedImage.java java/awt/image/ConvolveOp.java java/awt/image/ColorConvertOp.java +java/awt/image/DataBuffer.java +java/awt/image/DataBufferByte.java +java/awt/image/DataBufferDouble.java +java/awt/image/DataBufferFloat.java +java/awt/image/DataBufferInt.java +java/awt/image/DataBufferShort.java +java/awt/image/DataBufferUShort.java java/awt/image/IndexColorModel.java java/awt/image/LookupOp.java java/awt/image/RescaleOp.java @@ -94,6 +100,7 @@ java/lang/invoke/MutableCallSite.java java/lang/invoke/VolatileCallSite.java java/lang/LangHelper.java java/lang/management/PlatformComponent.java +java/lang/Package.java java/lang/ProcessImpl.java java/lang/PropertyConstants.java java/lang/ref/Reference.java @@ -152,12 +159,14 @@ sun/awt/AppContextDC.java sun/awt/EmbeddedFrame.java sun/awt/IkvmDataTransferer.java sun/awt/image/ByteComponentRaster.java +sun/awt/image/ByteInterleavedRaster.java sun/awt/image/BytePackedRaster.java sun/awt/image/GifImageDecoder.java sun/awt/image/IkvmImageDecoder.java sun/awt/image/ImageRepresentation.java sun/awt/image/ImagingLib.java sun/awt/image/IntegerComponentRaster.java +sun/awt/image/IntegerInterleavedRaster.java sun/awt/image/JPEGImageDecoder.java sun/awt/image/OffScreenImageSource.java sun/awt/image/ShortComponentRaster.java @@ -246,9 +255,11 @@ sun/print/UnixPrintServiceLookup.java sun/print/Win32PrintJob.java sun/print/Win32PrintService.java sun/print/Win32PrintServiceLookup.java +sun/reflect/CallerSensitive.java sun/reflect/MethodAccessor.java sun/reflect/Reflection.java sun/reflect/ReflectionFactory.java +sun/reflect/misc/ReflectUtil.java sun/security/jgss/wrapper/NativeGSSFactory.java sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/build/linux-amd64/gensrc/com/sun/accessibility/internal/resources/accessibility.java @@ -8572,13 +8583,6 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/ComponentColorModel.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/ComponentSampleModel.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/CropImageFilter.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBuffer.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferByte.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferDouble.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferFloat.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferInt.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferShort.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferUShort.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/DirectColorModel.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/FilteredImageSource.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/ImageConsumer.java @@ -8972,7 +8976,6 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/java/lang/OutOfMemoryError.java @OPENJDK7@/jdk/src/share/classes/java/lang/Override.java @OPENJDK7@/jdk/src/share/classes/java/lang/package-info.java -@OPENJDK7@/jdk/src/share/classes/java/lang/Package.java @OPENJDK7@/jdk/src/share/classes/java/lang/Process.java @OPENJDK7@/jdk/src/share/classes/java/lang/ProcessBuilder.java @OPENJDK7@/jdk/src/share/classes/java/lang/Readable.java @@ -11395,7 +11398,6 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/BufferedImageGraphicsConfig.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ByteArrayImageSource.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java -@OPENJDK7@/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/FileImageSource.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ImageConsumerQueue.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ImageDecoder.java @@ -11404,7 +11406,6 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ImageFormatException.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ImageWatched.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/InputStreamImageSource.java -@OPENJDK7@/jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/PixelConverter.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/PNGImageDecoder.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java @@ -12389,7 +12390,6 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/ConstructorUtil.java @OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/FieldUtil.java @OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java -@OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java @OPENJDK7@/jdk/src/share/classes/sun/reflect/SignatureIterator.java @OPENJDK7@/jdk/src/share/classes/sun/rmi/log/LogHandler.java @OPENJDK7@/jdk/src/share/classes/sun/rmi/log/LogInputStream.java diff --git a/openjdk/java/io/ObjectStreamClass.java b/openjdk/java/io/ObjectStreamClass.java index b448ab10..97489b1e 100644 --- a/openjdk/java/io/ObjectStreamClass.java +++ b/openjdk/java/io/ObjectStreamClass.java @@ -50,7 +50,10 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import sun.misc.Unsafe; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; import sun.reflect.ReflectionFactory; +import sun.reflect.misc.ReflectUtil; /** * Serialization's descriptor for classes. It contains the name and @@ -262,7 +265,17 @@ public class ObjectStreamClass implements Serializable { * * @return the <code>Class</code> instance that this descriptor represents */ + @CallerSensitive public Class<?> forClass() { + if (cl == null) { + return null; + } + if (System.getSecurityManager() != null) { + Class<?> caller = Reflection.getCallerClass(); + if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), cl.getClassLoader())) { + ReflectUtil.checkPackageAccess(cl); + } + } return cl; } @@ -1156,7 +1169,14 @@ public class ObjectStreamClass implements Serializable { end = end.getSuperclass(); } + HashSet<String> oscNames = new HashSet<>(3); + for (ObjectStreamClass d = this; d != null; d = d.superDesc) { + if (oscNames.contains(d.name)) { + throw new InvalidClassException("Circular reference."); + } else { + oscNames.add(d.name); + } // search up inheritance hierarchy for class with matching name String searchName = (d.cl != null) ? d.cl.getName() : d.name; diff --git a/openjdk/java/lang/Class.java b/openjdk/java/lang/Class.java index 20f35534..bbc1d241 100644 --- a/openjdk/java/lang/Class.java +++ b/openjdk/java/lang/Class.java @@ -53,6 +53,7 @@ import java.util.Set; import java.util.Map; import java.util.HashMap; import sun.misc.Unsafe; +import sun.reflect.CallerSensitive; import sun.reflect.ConstantPool; import sun.reflect.Reflection; import sun.reflect.ReflectionFactory; @@ -65,7 +66,9 @@ import sun.reflect.generics.repository.ConstructorRepository; import sun.reflect.generics.scope.ClassScope; import sun.security.util.SecurityConstants; import java.lang.annotation.Annotation; -import sun.reflect.annotation.AnnotationType; +import java.lang.reflect.Proxy; +import sun.reflect.annotation.*; +import sun.reflect.misc.ReflectUtil; import cli.System.Runtime.Serialization.IObjectReference; import cli.System.Runtime.Serialization.SerializationException; import cli.System.Runtime.Serialization.SerializationInfo; @@ -281,10 +284,11 @@ public final * by this method fails * @exception ClassNotFoundException if the class cannot be located */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { - return forName0(className, true, ClassLoader.getCallerClassLoader()); + return forName0(className, true, + ClassLoader.getClassLoader(Reflection.getCallerClass())); } @@ -348,7 +352,7 @@ public final * @see java.lang.ClassLoader * @since 1.2 */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException @@ -356,7 +360,7 @@ public final if (loader == null) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = ClassLoader.getCallerClassLoader(); + ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass()); if (ccl != null) { sm.checkPermission( SecurityConstants.GET_CLASSLOADER_PERMISSION); @@ -418,19 +422,14 @@ public final * </ul> * */ - @ikvm.internal.HasCallerID + @CallerSensitive public T newInstance() throws InstantiationException, IllegalAccessException { if (System.getSecurityManager() != null) { - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false); } - return newInstance0(ikvm.internal.CallerID.getCallerID()); - } - private T newInstance0(ikvm.internal.CallerID callerID) - throws InstantiationException, IllegalAccessException - { // NOTE: the following code may not be strictly correct under // the current Java memory model. @@ -464,7 +463,7 @@ public final // Security check (same as in java.lang.reflect.Constructor) int modifiers = tmpConstructor.getModifiers(); if (!Reflection.quickCheckMemberAccess(this, modifiers)) { - Class<?> caller = callerID.getCallerClass(); + Class<?> caller = Reflection.getCallerClass(); if (newInstanceCallerCache != caller) { Reflection.ensureMemberAccess(caller, this, null, modifiers); newInstanceCallerCache = caller; @@ -705,17 +704,14 @@ public final * @see SecurityManager#checkPermission * @see java.lang.RuntimePermission */ - @ikvm.internal.HasCallerID + @CallerSensitive public ClassLoader getClassLoader() { ClassLoader cl = getClassLoader0(); if (cl == null) return null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = ClassLoader.getCallerClassLoader(); - if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass()); } return cl; } @@ -996,6 +992,7 @@ public final * that class is a local or anonymous class; otherwise {@code null}. * @since 1.5 */ + @CallerSensitive public Method getEnclosingMethod() { EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); @@ -1017,13 +1014,22 @@ public final for(int i = 0; i < parameterClasses.length; i++) parameterClasses[i] = toClass(parameterTypes[i]); + // Perform access check + Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass(); + // be very careful not to change the stack depth of this + // checkMemberAccess call for security reasons + // see java.lang.SecurityManager.checkMemberAccess + // + // Note that we need to do this on the enclosing class + enclosingCandidate.checkMemberAccess(Member.DECLARED, + Reflection.getCallerClass(), true); /* * Loop over all declared methods; match method name, * number of and type of parameters, *and* return * type. Matching return type is also necessary * because of covariant returns, etc. */ - for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) { + for(Method m: enclosingCandidate.getDeclaredMethods()) { if (m.getName().equals(enclosingInfo.getName()) ) { Class<?>[] candidateParamClasses = m.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { @@ -1124,6 +1130,7 @@ public final * that class is a local or anonymous class; otherwise {@code null}. * @since 1.5 */ + @CallerSensitive public Constructor<?> getEnclosingConstructor() { EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); @@ -1144,11 +1151,20 @@ public final for(int i = 0; i < parameterClasses.length; i++) parameterClasses[i] = toClass(parameterTypes[i]); + // Perform access check + Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass(); + // be very careful not to change the stack depth of this + // checkMemberAccess call for security reasons + // see java.lang.SecurityManager.checkMemberAccess + // + // Note that we need to do this on the enclosing class + enclosingCandidate.checkMemberAccess(Member.DECLARED, + Reflection.getCallerClass(), true); /* * Loop over all declared constructors; match number * of and type of parameters. */ - for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) { + for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) { Class<?>[] candidateParamClasses = c.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { boolean matches = true; @@ -1190,6 +1206,7 @@ public final * @return the immediately enclosing class of the underlying class * @since 1.5 */ + @CallerSensitive public Class<?> getEnclosingClass() { // There are five kinds of classes (or interfaces): // a) Top level classes @@ -1203,18 +1220,24 @@ public final // attribute if and only if it is a local class or an // anonymous class. EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); + Class<?> enclosingCandidate; if (enclosingInfo == null) { // This is a top level or a nested class or an inner class (a, b, or c) - return getDeclaringClass(); + enclosingCandidate = getDeclaringClass(); } else { Class<?> enclosingClass = enclosingInfo.getEnclosingClass(); // This is a local class or an anonymous class (d or e) if (enclosingClass == this || enclosingClass == null) throw new InternalError("Malformed enclosing method information"); else - return enclosingClass; + enclosingCandidate = enclosingClass; } + + if (enclosingCandidate != null) + enclosingCandidate.checkPackageAccess( + ClassLoader.getClassLoader(Reflection.getCallerClass()), true); + return enclosingCandidate; } /** @@ -1397,12 +1420,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Class<?>[] getClasses() { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false); // Privileged so this implementation can look at DECLARED classes, // something the caller might not have privilege to do. The code here @@ -1473,12 +1496,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Field[] getFields() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return copyFields(privateGetPublicFields(null)); } @@ -1525,12 +1548,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Method[] getMethods() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return copyMethods(privateGetPublicMethods()); } @@ -1575,12 +1598,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Constructor<?>[] getConstructors() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return copyConstructors(privateGetDeclaredConstructors(true)); } @@ -1634,13 +1657,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Field getField(String name) throws NoSuchFieldException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); Field field = getField0(name); if (field == null) { throw new NoSuchFieldException(name); @@ -1720,13 +1743,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); Method method = getMethod0(name, parameterTypes); if (method == null) { throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); @@ -1775,13 +1798,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return getConstructor0(parameterTypes, Member.PUBLIC); } @@ -1819,12 +1842,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Class<?>[] getDeclaredClasses() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false); return getDeclaredClasses0(); } @@ -1864,12 +1887,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Field[] getDeclaredFields() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return copyFields(privateGetDeclaredFields(false)); } @@ -1913,12 +1936,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Method[] getDeclaredMethods() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return copyMethods(privateGetDeclaredMethods(false)); } @@ -1959,12 +1982,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Constructor<?>[] getDeclaredConstructors() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return copyConstructors(privateGetDeclaredConstructors(false)); } @@ -2003,13 +2026,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); Field field = searchFields(privateGetDeclaredFields(false), name); if (field == null) { throw new NoSuchFieldException(name); @@ -2059,13 +2082,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); if (method == null) { throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); @@ -2110,13 +2133,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return getConstructor0(parameterTypes, Member.DECLARED); } @@ -2274,31 +2297,69 @@ public final */ static native Class getPrimitiveClass(String name); + private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) { + if (smgr.getClass() == SecurityManager.class) return false; + + Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class}; + return smgr.getClass().getMethod0("checkMemberAccess", paramTypes). + getDeclaringClass() != SecurityManager.class; + } + /* * Check if client is allowed to access members. If access is denied, * throw a SecurityException. * - * Be very careful not to change the stack depth of this checkMemberAccess - * call for security reasons. - * See java.lang.SecurityManager.checkMemberAccess. + * This method also enforces package access. * * <p> Default policy: allow all clients access with normal Java access * control. */ - private void checkMemberAccess(int which, ClassLoader ccl) { - SecurityManager s = System.getSecurityManager(); + private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) { + final SecurityManager s = System.getSecurityManager(); if (s != null) { - s.checkMemberAccess(this, which); - ClassLoader cl = getClassLoader0(); - if ((ccl != null) && (ccl != cl) && - ((cl == null) || !cl.isAncestor(ccl))) { + final ClassLoader ccl = ClassLoader.getClassLoader(caller); + final ClassLoader cl = getClassLoader0(); + if (!isCheckMemberAccessOverridden(s)) { + // Inlined SecurityManager.checkMemberAccess + if (which != Member.PUBLIC) { + if (ccl != cl) { + s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); + } + } + } else { + // Don't refactor; otherwise break the stack depth for + // checkMemberAccess of subclasses of SecurityManager as specified. + s.checkMemberAccess(this, which); + } + this.checkPackageAccess(ccl, checkProxyInterfaces); + } + } + + /* + * Checks if a client loaded in ClassLoader ccl is allowed to access this + * class under the current package access policy. If access is denied, + * throw a SecurityException. + */ + private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) { + final SecurityManager s = System.getSecurityManager(); + if (s != null) { + final ClassLoader cl = getClassLoader0(); + if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) { String name = this.getName(); int i = name.lastIndexOf('.'); if (i != -1) { - s.checkPackageAccess(name.substring(0, i)); + // skip the package access check on a proxy class in default proxy package + String pkg = name.substring(0, i); + if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) { + s.checkPackageAccess(pkg); + } } } + // check package access on the proxy interfaces + if (checkProxyInterfaces && Proxy.isProxyClass(this)) { + ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces()); + } } } diff --git a/openjdk/java/lang/ClassLoader.java b/openjdk/java/lang/ClassLoader.java index 8162ba81..57c1ee3e 100644 --- a/openjdk/java/lang/ClassLoader.java +++ b/openjdk/java/lang/ClassLoader.java @@ -56,6 +56,7 @@ import sun.misc.CompoundEnumeration; import sun.misc.Resource; import sun.misc.URLClassPath; import sun.misc.VM; +import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import sun.security.util.SecurityConstants; @@ -1256,9 +1257,11 @@ public abstract class ClassLoader { * * @since 1.7 */ - @ikvm.internal.HasCallerID + @CallerSensitive protected static boolean registerAsParallelCapable() { - return ParallelLoaders.register(ikvm.internal.CallerID.getCallerID().getCallerClass()); + Class<? extends ClassLoader> callerClass = + Reflection.getCallerClass().asSubclass(ClassLoader.class); + return ParallelLoaders.register(callerClass); } /** @@ -1402,15 +1405,13 @@ public abstract class ClassLoader { * * @since 1.2 */ + @CallerSensitive public final ClassLoader getParent() { if (parent == null) return null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = getCallerClassLoader(); - if (ccl != null && !isAncestor(ccl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + checkClassLoaderPermission(parent, Reflection.getCallerClass()); } return parent; } @@ -1470,7 +1471,7 @@ public abstract class ClassLoader { * * @revised 1.4 */ - @ikvm.internal.HasCallerID + @CallerSensitive public static ClassLoader getSystemClassLoader() { initSystemClassLoader(); if (scl == null) { @@ -1478,10 +1479,7 @@ public abstract class ClassLoader { } SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = getCallerClassLoader(); - if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + checkClassLoaderPermission(scl, Reflection.getCallerClass()); } return scl; } @@ -1529,13 +1527,25 @@ public abstract class ClassLoader { return false; } - // Returns the invoker's class loader, or null if none. - // NOTE: This must always be invoked when there is exactly one intervening - // frame from the core libraries on the stack between this method's - // invocation and the desired invoker. - static ClassLoader getCallerClassLoader() { - // NOTE use of more generic Reflection.getCallerClass() - Class caller = Reflection.getCallerClass(3); + // Tests if class loader access requires "getClassLoader" permission + // check. A class loader 'from' can access class loader 'to' if + // class loader 'from' is same as class loader 'to' or an ancestor + // of 'to'. The class loader in a system domain can access + // any class loader. + private static boolean needsClassLoaderPermissionCheck(ClassLoader from, + ClassLoader to) + { + if (from == to) + return false; + + if (from == null) + return false; + + return !to.isAncestor(from); + } + + // Returns the class's class loader, or null if none. + static ClassLoader getClassLoader(Class<?> caller) { // This can be null if the VM is requesting it if (caller == null) { return null; @@ -1544,6 +1554,17 @@ public abstract class ClassLoader { return caller.getClassLoader0(); } + static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + // caller can be null if the VM is requesting it + ClassLoader ccl = getClassLoader(caller); + if (needsClassLoaderPermissionCheck(ccl, cl)) { + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); + } + } + } + // The class loader for the system // @GuardedBy("ClassLoader.class") private static ClassLoader scl; diff --git a/openjdk/java/lang/System.java b/openjdk/java/lang/System.java index e6f4d3cc..e74187b9 100644 --- a/openjdk/java/lang/System.java +++ b/openjdk/java/lang/System.java @@ -33,7 +33,7 @@ import java.security.PrivilegedAction; import java.security.AllPermission; import java.nio.channels.Channel; import java.nio.channels.spi.SelectorProvider; - +import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import sun.security.util.SecurityConstants; @@ -1105,9 +1105,9 @@ public final class System { * @see java.lang.Runtime#load(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static void load(String filename) { - Runtime.getRuntime().load0(Reflection.getCallerClass(2), filename); + Runtime.getRuntime().load0(Reflection.getCallerClass(), filename); } /** @@ -1131,9 +1131,9 @@ public final class System { * @see java.lang.Runtime#loadLibrary(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static void loadLibrary(String libname) { - Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(2), libname); + Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname); } /** @@ -1160,7 +1160,6 @@ public final class System { return "lib" + libname + ".so"; } } - /* returns the class of the caller. */ static Class<?> getCallerClass() { // NOTE use of more generic Reflection.getCallerClass() diff --git a/openjdk/java/lang/Thread.java b/openjdk/java/lang/Thread.java index 3de50ff7..e8f57d06 100644 --- a/openjdk/java/lang/Thread.java +++ b/openjdk/java/lang/Thread.java @@ -37,6 +37,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.LockSupport; import sun.nio.ch.Interruptible; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; import sun.security.util.SecurityConstants; @@ -169,7 +171,7 @@ class Thread implements Runnable { private cli.System.Threading.Thread nativeThread; private Throwable stillborn; private boolean running; // used only for coordination with stop0(), is never set to false - private boolean interruptPending; + private volatile boolean interruptPending; private volatile boolean nativeInterruptPending; private volatile boolean interruptableWait; private boolean timedWait; @@ -1228,7 +1230,12 @@ class Thread implements Runnable { * @revised 6.0 */ public static boolean interrupted() { - return currentThread().isInterrupted(true); + Thread current = currentThread(); + if (!current.interruptPending) { + return false; + } + current.interruptPending = false; + return true; } /** @@ -1245,22 +1252,7 @@ class Thread implements Runnable { * @revised 6.0 */ public boolean isInterrupted() { - return isInterrupted(false); - } - - /** - * Tests if some Thread has been interrupted. The interrupted state - * is reset or not based on the value of ClearInterrupted that is - * passed. - */ - private boolean isInterrupted(boolean ClearInterrupted) { - synchronized (lock) { - boolean b = interruptPending; - if (ClearInterrupted) { - interruptPending = false; - } - return b; - } + return interruptPending; } /** @@ -1723,19 +1715,18 @@ class Thread implements Runnable { * * @since 1.2 */ + @CallerSensitive public ClassLoader getContextClassLoader() { if (contextClassLoader == ClassLoader.DUMMY) { contextClassLoader = ClassLoader.getSystemClassLoader(); } if (contextClassLoader == null) return null; + SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = ClassLoader.getCallerClassLoader(); - if (ccl != null && ccl != contextClassLoader && - !contextClassLoader.isAncestor(ccl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + ClassLoader.checkClassLoaderPermission(contextClassLoader, + Reflection.getCallerClass()); } return contextClassLoader; } diff --git a/openjdk/java/lang/invoke/MethodHandles.java b/openjdk/java/lang/invoke/MethodHandles.java index 710d6ab0..6f0db408 100644 --- a/openjdk/java/lang/invoke/MethodHandles.java +++ b/openjdk/java/lang/invoke/MethodHandles.java @@ -33,11 +33,10 @@ import sun.invoke.util.Wrapper; import java.util.List; import java.util.ArrayList; import java.util.Arrays; +import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; -import ikvm.internal.CallerID; -import ikvm.internal.HasCallerID; /** * This class consists exclusively of static methods that operate on or return @@ -68,9 +67,9 @@ public class MethodHandles { * This lookup object is a <em>capability</em> which may be delegated to trusted agents. * Do not store it in place where untrusted code can access it. */ - @HasCallerID + @CallerSensitive public static Lookup lookup() { - return new Lookup(CallerID.getCallerID()); + return new Lookup(Reflection.getCallerClass()); } /** @@ -412,14 +411,9 @@ public class MethodHandles { * Also, don't make it private, lest javac interpose * an access$N method. */ - Lookup(CallerID caller) { - this(caller.getCallerClass(), ALL_MODES); - // make sure we haven't accidentally picked up a privileged class: - checkUnprivilegedlookupClass(lookupClass); - } - Lookup(Class<?> lookupClass) { this(lookupClass, ALL_MODES); + checkUnprivilegedlookupClass(lookupClass); } private Lookup(Class<?> lookupClass, int allowedModes) { diff --git a/openjdk/java/lang/reflect/Constructor.java b/openjdk/java/lang/reflect/Constructor.java index e62e8772..b13d30a5 100644 --- a/openjdk/java/lang/reflect/Constructor.java +++ b/openjdk/java/lang/reflect/Constructor.java @@ -25,6 +25,7 @@ package java.lang.reflect; +import sun.reflect.CallerSensitive; import sun.reflect.ConstructorAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.ConstructorRepository; @@ -501,15 +502,14 @@ public final * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public T newInstance(Object ... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = Reflection.getCallerClass(2); - + Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, null, modifiers); } } diff --git a/openjdk/java/lang/reflect/Field.java b/openjdk/java/lang/reflect/Field.java index c796d20a..b2cb46b3 100644 --- a/openjdk/java/lang/reflect/Field.java +++ b/openjdk/java/lang/reflect/Field.java @@ -25,6 +25,7 @@ package java.lang.reflect; +import sun.reflect.CallerSensitive; import sun.reflect.FieldAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.FieldRepository; @@ -34,7 +35,6 @@ import sun.reflect.generics.scope.ClassScope; import java.lang.annotation.Annotation; import java.util.Map; import sun.reflect.annotation.AnnotationParser; -import ikvm.internal.CallerID; /** @@ -365,11 +365,16 @@ class Field extends AccessibleObject implements Member { * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).get(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).get(obj); } /** @@ -394,11 +399,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public boolean getBoolean(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getBoolean(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getBoolean(obj); } /** @@ -423,11 +433,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public byte getByte(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getByte(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getByte(obj); } /** @@ -454,11 +469,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public char getChar(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getChar(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getChar(obj); } /** @@ -485,11 +505,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public short getShort(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getShort(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getShort(obj); } /** @@ -516,11 +541,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public int getInt(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getInt(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getInt(obj); } /** @@ -547,11 +577,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public long getLong(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getLong(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getLong(obj); } /** @@ -578,11 +613,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public float getFloat(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getFloat(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getFloat(obj); } /** @@ -609,11 +649,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public double getDouble(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getDouble(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getDouble(obj); } /** @@ -682,11 +727,16 @@ class Field extends AccessibleObject implements Member { * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).set(obj, value); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).set(obj, value); } /** @@ -713,11 +763,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setBoolean(Object obj, boolean z) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setBoolean(obj, z); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setBoolean(obj, z); } /** @@ -744,11 +799,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setByte(Object obj, byte b) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setByte(obj, b); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setByte(obj, b); } /** @@ -775,11 +835,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setChar(Object obj, char c) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setChar(obj, c); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setChar(obj, c); } /** @@ -806,11 +871,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setShort(Object obj, short s) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setShort(obj, s); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setShort(obj, s); } /** @@ -837,11 +907,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setInt(Object obj, int i) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setInt(obj, i); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setInt(obj, i); } /** @@ -868,11 +943,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setLong(Object obj, long l) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setLong(obj, l); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setLong(obj, l); } /** @@ -899,11 +979,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setFloat(Object obj, float f) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setFloat(obj, f); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setFloat(obj, f); } /** @@ -930,21 +1015,25 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setDouble(Object obj, double d) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setDouble(obj, d); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setDouble(obj, d); } - // Convenience routine which performs security checks - private FieldAccessor getFieldAccessor(Object obj, CallerID callerID) + // security check is done before calling this method + private FieldAccessor getFieldAccessor(Object obj) throws IllegalAccessException { - doSecurityCheck(obj, callerID); boolean ov = override; - FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor; - return (a != null)? a : acquireFieldAccessor(ov); + FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor; + return (a != null) ? a : acquireFieldAccessor(ov); } // NOTE that there is no synchronization used here. It is correct @@ -989,19 +1078,6 @@ class Field extends AccessibleObject implements Member { } } - // NOTE: be very careful if you change the stack depth of this - // routine. The depth of the "getCallerClass" call is hardwired so - // that the compiler can have an easier time if this gets inlined. - private void doSecurityCheck(Object obj, CallerID callerID) throws IllegalAccessException { - if (!override) { - if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = callerID.getCallerClass(); - - checkAccess(caller, clazz, obj, modifiers); - } - } - } - /* * Utility routine to paper over array type names */ diff --git a/openjdk/java/lang/reflect/Method.java b/openjdk/java/lang/reflect/Method.java index b1548d6b..dce789a4 100644 --- a/openjdk/java/lang/reflect/Method.java +++ b/openjdk/java/lang/reflect/Method.java @@ -26,6 +26,7 @@ package java.lang.reflect; import ikvm.internal.CallerID; +import sun.reflect.CallerSensitive; import sun.reflect.MethodAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.MethodRepository; @@ -578,15 +579,14 @@ public final * @exception ExceptionInInitializerError if the initialization * provoked by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = CallerID.getCallerID().getCallerClass(); - + Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, obj, modifiers); } } diff --git a/openjdk/java/security/AccessController.java b/openjdk/java/security/AccessController.java index 60b7722a..19d4af96 100644 --- a/openjdk/java/security/AccessController.java +++ b/openjdk/java/security/AccessController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ package java.security; import ikvm.internal.CallerID; import sun.misc.Unsafe; import sun.security.util.Debug; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; /** * <p> The AccessController class is used for access control operations @@ -317,7 +319,7 @@ public final class AccessController { * @see java.security.DomainCombiner */ - @ikvm.internal.HasCallerID + @CallerSensitive public static <T> T doPrivileged(PrivilegedAction<T> action) { return (T)doPrivileged(action, null, CallerID.getCallerID()); } @@ -344,14 +346,14 @@ public final class AccessController { * * @since 1.6 */ + @CallerSensitive public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) { - - DomainCombiner dc = null; AccessControlContext acc = getStackAccessControlContext(); - if (acc == null || (dc = acc.getAssignedCombiner()) == null) { + if (acc == null) { return AccessController.doPrivileged(action); } - return AccessController.doPrivileged(action, preserveCombiner(dc)); + DomainCombiner dc = acc.getAssignedCombiner(); + return AccessController.doPrivileged(action, preserveCombiner(dc, Reflection.getCallerClass())); } @@ -382,7 +384,7 @@ public final class AccessController { * @see #doPrivileged(PrivilegedAction) * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static <T> T doPrivileged(PrivilegedAction<T> action, AccessControlContext context) { return (T)doPrivileged(action, context, CallerID.getCallerID()); @@ -412,7 +414,7 @@ public final class AccessController { * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction) * @see java.security.DomainCombiner */ - @ikvm.internal.HasCallerID + @CallerSensitive public static <T> T doPrivileged(PrivilegedExceptionAction<T> action) throws PrivilegedActionException { @@ -445,41 +447,39 @@ public final class AccessController { * * @since 1.6 */ + @CallerSensitive public static <T> T doPrivilegedWithCombiner (PrivilegedExceptionAction<T> action) throws PrivilegedActionException { - DomainCombiner dc = null; AccessControlContext acc = getStackAccessControlContext(); - if (acc == null || (dc = acc.getAssignedCombiner()) == null) { + if (acc == null) { return AccessController.doPrivileged(action); } - return AccessController.doPrivileged(action, preserveCombiner(dc)); + DomainCombiner dc = acc.getAssignedCombiner(); + return AccessController.doPrivileged(action, preserveCombiner(dc, Reflection.getCallerClass())); } /** * preserve the combiner across the doPrivileged call */ - private static AccessControlContext preserveCombiner - (DomainCombiner combiner) { - - /** - * callerClass[0] = Reflection.getCallerClass - * callerClass[1] = AccessController.preserveCombiner - * callerClass[2] = AccessController.doPrivileged - * callerClass[3] = caller - */ - final Class callerClass = sun.reflect.Reflection.getCallerClass(3); + private static AccessControlContext preserveCombiner(DomainCombiner combiner, + final Class<?> caller) { ProtectionDomain callerPd = doPrivileged (new PrivilegedAction<ProtectionDomain>() { public ProtectionDomain run() { - return callerClass.getProtectionDomain(); + return caller.getProtectionDomain(); } }); // perform 'combine' on the caller of doPrivileged, // even if the caller is from the bootclasspath ProtectionDomain[] pds = new ProtectionDomain[] {callerPd}; - return new AccessControlContext(combiner.combine(pds, null), combiner); + if (combiner == null) { + return new AccessControlContext(pds); + } else { + return new AccessControlContext(combiner.combine(pds, null), + combiner); + } } @@ -512,7 +512,7 @@ public final class AccessController { * @see #doPrivileged(PrivilegedAction) * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context) diff --git a/openjdk/java/sql/DriverManager.java b/openjdk/java/sql/DriverManager.java index 6c35058d..8698345c 100644 --- a/openjdk/java/sql/DriverManager.java +++ b/openjdk/java/sql/DriverManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,13 @@ package java.sql; -import ikvm.internal.CallerID; import java.util.Iterator; import java.util.ServiceLoader; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.concurrent.CopyOnWriteArrayList; - +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; /** * <P>The basic service for managing a set of JDBC drivers.<br> @@ -181,15 +181,10 @@ public class DriverManager { * @return a Connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url, java.util.Properties info) throws SQLException { - - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -205,15 +200,11 @@ public class DriverManager { * @return a connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url, String user, String password) throws SQLException { java.util.Properties info = new java.util.Properties(); - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - if (user != null) { info.put("user", user); } @@ -221,7 +212,7 @@ public class DriverManager { info.put("password", password); } - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -234,17 +225,12 @@ public class DriverManager { * @return a connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url) throws SQLException { java.util.Properties info = new java.util.Properties(); - - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -258,22 +244,20 @@ public class DriverManager { * that can connect to the given URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Driver getDriver(String url) throws SQLException { println("DriverManager.getDriver(\"" + url + "\")"); - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); + Class<?> callerClass = Reflection.getCallerClass(); // Walk through the loaded registeredDrivers attempting to locate someone // who understands the given URL. for (DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if(isDriverAllowed(aDriver.driver, callerCL)) { + if(isDriverAllowed(aDriver.driver, callerClass)) { try { if(aDriver.driver.acceptsURL(url)) { // Success! @@ -287,6 +271,7 @@ public class DriverManager { } else { println(" skipping: " + aDriver.driver.getClass().getName()); } + } println("getDriver: no suitable driver"); @@ -326,21 +311,18 @@ public class DriverManager { * @param driver the JDBC Driver to drop * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static synchronized void deregisterDriver(Driver driver) throws SQLException { if (driver == null) { return; } - // Gets the classloader of the code that called this method, - // may be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); println("DriverManager.deregisterDriver: " + driver); DriverInfo aDriver = new DriverInfo(driver); if(registeredDrivers.contains(aDriver)) { - if (isDriverAllowed(driver, callerCL)) { + if (isDriverAllowed(driver, Reflection.getCallerClass())) { registeredDrivers.remove(aDriver); } else { // If the caller does not have permission to load the driver then @@ -361,25 +343,22 @@ public class DriverManager { * * @return the list of JDBC Drivers loaded by the caller's class loader */ - @ikvm.internal.HasCallerID + @CallerSensitive public static java.util.Enumeration<Driver> getDrivers() { java.util.Vector<Driver> result = new java.util.Vector<Driver>(); - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); + Class<?> callerClass = Reflection.getCallerClass(); // Walk through the loaded registeredDrivers. for(DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if(isDriverAllowed(aDriver.driver, callerCL)) { + if(isDriverAllowed(aDriver.driver, callerClass)) { result.addElement(aDriver.driver); } else { println(" skipping: " + aDriver.getClass().getName()); } } - return (result.elements()); } @@ -471,6 +450,11 @@ public class DriverManager { // Indicates whether the class object that would be created if the code calling // DriverManager is accessible. + private static boolean isDriverAllowed(Driver driver, Class<?> caller) { + ClassLoader callerCL = caller != null ? caller.getClassLoader() : null; + return isDriverAllowed(driver, callerCL); + } + private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) { boolean result = false; if(driver != null) { @@ -523,7 +507,7 @@ public class DriverManager { */ try{ while(driversIterator.hasNext()) { - println(" Loading done by the java.util.ServiceLoader : "+driversIterator.next()); + driversIterator.next(); } } catch(Throwable t) { // Do nothing @@ -553,18 +537,19 @@ public class DriverManager { // Worker method called by the public getConnection() methods. private static Connection getConnection( - String url, java.util.Properties info, ClassLoader callerCL) throws SQLException { + String url, java.util.Properties info, Class<?> caller) throws SQLException { /* * When callerCl is null, we should check the application's * (which is invoking this class indirectly) * classloader, so that the JDBC driver class outside rt.jar * can be loaded from here. */ - synchronized(DriverManager.class) { - // synchronize loading of the correct classloader. - if(callerCL == null) { - callerCL = Thread.currentThread().getContextClassLoader(); - } + ClassLoader callerCL = caller != null ? caller.getClassLoader() : null; + synchronized (DriverManager.class) { + // synchronize loading of the correct classloader. + if (callerCL == null) { + callerCL = Thread.currentThread().getContextClassLoader(); + } } if(url == null) { @@ -610,7 +595,6 @@ public class DriverManager { println("getConnection: no suitable driver found for "+ url); throw new SQLException("No suitable driver found for "+ url, "08001"); } - } /* diff --git a/openjdk/java/util/ResourceBundle.java b/openjdk/java/util/ResourceBundle.java index b572875e..98ee3c51 100644 --- a/openjdk/java/util/ResourceBundle.java +++ b/openjdk/java/util/ResourceBundle.java @@ -55,6 +55,8 @@ import java.security.PrivilegedExceptionAction; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.jar.JarEntry; + +import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import sun.util.locale.BaseLocale; import sun.util.locale.LocaleObjectCache; @@ -412,11 +414,10 @@ public abstract class ResourceBundle { /* * Automatic determination of the ClassLoader to be used to load - * resources on behalf of the client. N.B. The client is getLoader's - * caller's caller. + * resources on behalf of the client. */ - private static ClassLoader getLoader(Class c) { - ClassLoader cl = (c == null) ? null : c.getClassLoader(); + private static ClassLoader getLoader(Class<?> caller) { + ClassLoader cl = caller == null ? null : caller.getClassLoader(); if (cl == null) { // When the caller's loader is the boot class loader, cl is null // here. In that case, ClassLoader.getSystemClassLoader() may @@ -714,12 +715,12 @@ public abstract class ResourceBundle { * if no resource bundle for the specified base name can be found * @return a resource bundle for the given base name and the default locale */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final ResourceBundle getBundle(String baseName) { return getBundleImpl(baseName, Locale.getDefault(), /* must determine loader here, else we break stack invariant */ - getLoader(Reflection.getCallerClass(2)), + getLoader(Reflection.getCallerClass()), Control.INSTANCE); } @@ -757,12 +758,12 @@ public abstract class ResourceBundle { * needed. * @since 1.6 */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final ResourceBundle getBundle(String baseName, Control control) { return getBundleImpl(baseName, Locale.getDefault(), /* must determine loader here, else we break stack invariant */ - getLoader(Reflection.getCallerClass(2)), + getLoader(Reflection.getCallerClass()), control); } @@ -787,13 +788,13 @@ public abstract class ResourceBundle { * if no resource bundle for the specified base name can be found * @return a resource bundle for the given base name and locale */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final ResourceBundle getBundle(String baseName, Locale locale) { return getBundleImpl(baseName, locale, /* must determine loader here, else we break stack invariant */ - getLoader(Reflection.getCallerClass(2)), + getLoader(Reflection.getCallerClass()), Control.INSTANCE); } @@ -834,12 +835,12 @@ public abstract class ResourceBundle { * needed. * @since 1.6 */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final ResourceBundle getBundle(String baseName, Locale targetLocale, Control control) { return getBundleImpl(baseName, targetLocale, /* must determine loader here, else we break stack invariant */ - getLoader(Reflection.getCallerClass(2)), + getLoader(Reflection.getCallerClass()), control); } @@ -1675,9 +1676,9 @@ public abstract class ResourceBundle { * @since 1.6 * @see ResourceBundle.Control#getTimeToLive(String,Locale) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final void clearCache() { - clearCache(getLoader(Reflection.getCallerClass(2))); + clearCache(getLoader(Reflection.getCallerClass())); } /** diff --git a/openjdk/response.txt b/openjdk/response.txt index 59ddd33c..4fc0f4f4 100644 --- a/openjdk/response.txt +++ b/openjdk/response.txt @@ -52,6 +52,7 @@ assembly.class sun/nio/cs/*.class sun/nio/fs/*.class sun/reflect/*.class + sun/reflect/misc/*.class ../classpath/gnu/java/net/protocol/ikvmres/*.class ../classpath/ikvm/extensions/*.class ../classpath/ikvm/internal/*.class @@ -167,7 +168,7 @@ assembly.class } { -out:IKVM.OpenJDK.Corba.dll - -baseaddress:0x56C30000 + -baseaddress:0x56C60000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/corba/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/cosnaming/jndiprovider.properties @OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/activation/*.class @@ -285,7 +286,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.API.dll - -baseaddress:0x57290000 + -baseaddress:0x572C0000 @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/*.class @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/datatype/*.class @OPENJDK7@/build/linux-amd64/impsrc/javax/xml/namespace/*.class @@ -318,7 +319,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.XPath.dll - -baseaddress:0x57350000 + -baseaddress:0x57380000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xalan/internal/res/* @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/extensions/*.class @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/res/*.class @@ -343,7 +344,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.Parse.dll - -baseaddress:0x576B0000 + -baseaddress:0x576E0000 -resource:com/sun/org/apache/xml/internal/serialize/HTMLEntities.res=@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/serialize/HTMLEntities.res -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xerces/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/serializer/* @@ -404,7 +405,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.Transform.dll - -baseaddress:0x57E60000 + -baseaddress:0x57E90000 @OPENJDK7@/build/linux-amd64/impsrc/com/sun/java_cup/internal/runtime/*.class @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/*.class @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/classfile/*.class @@ -428,7 +429,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.Bind.dll - -baseaddress:0x58280000 + -baseaddress:0x582B0000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/xml/bind/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/bind/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/fastinfoset/* @@ -487,7 +488,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.WebServices.dll - -baseaddress:0x585E0000 + -baseaddress:0x58610000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/messaging/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/ws/* @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/amx/*.class @@ -607,7 +608,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.Crypto.dll - -baseaddress:0x58B50000 + -baseaddress:0x58B80000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/security/* @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/*.class @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/*.class @@ -643,7 +644,7 @@ assembly.class } { -out:IKVM.OpenJDK.SwingAWT.dll - -baseaddress:0x58CA0000 + -baseaddress:0x58CD0000 -remap:swingawt.xml -resource:META-INF/services/sun.java2d.pipe.RenderingEngine=resources/META-INF/services/sun.java2d.pipe.RenderingEngine -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/sun.java2d.cmm.PCMM @@ -743,7 +744,7 @@ assembly.class } { -out:IKVM.OpenJDK.Charsets.dll - -baseaddress:0x59E40000 + -baseaddress:0x59E70000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/sun/nio/cs/ext/sjis0213.dat -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/META-INF/services/java.nio.charset.spi.CharsetProvider @OPENJDK7@/build/linux-amd64/gensrc/sun/nio/cs/ext/*.class @@ -752,7 +753,7 @@ assembly.class } { -out:IKVM.OpenJDK.Util.dll - -baseaddress:0x5A4D0000 + -baseaddress:0x5A500000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/java/util/jar/pack/intrinsic.properties -recurse:resources.zip/sun/launcher/resources/* -resource:META-INF/services/java.nio.file.spi.FileSystemProvider=@OPENJDK7@/jdk/src/share/demo/nio/zipfs/src/META-INF/services/java.nio.file.spi.FileSystemProvider @@ -775,7 +776,7 @@ assembly.class } { -out:IKVM.OpenJDK.Text.dll - -baseaddress:0x5AAA0000 + -baseaddress:0x5AAD0000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/text/* @OPENJDK7@/build/linux-amd64/j2re-image/lib/ext/localedata.jar @OPENJDK7@/jdk/src/share/classes/java/text/*.class @@ -787,7 +788,7 @@ assembly.class } { -out:IKVM.OpenJDK.Security.dll - -baseaddress:0x5AD10000 + -baseaddress:0x5AD40000 -remap:security.xml sun/security/jgss/wrapper/*.class @OPENJDK7@/jdk/src/share/classes/com/sun/crypto/provider/*.class @@ -858,7 +859,7 @@ assembly.class } { -out:IKVM.OpenJDK.Management.dll - -baseaddress:0x5B520000 + -baseaddress:0x5B550000 com/sun/management/*.class java/lang/management/*.class sun/management/*.class @@ -892,7 +893,7 @@ assembly.class } { -out:IKVM.OpenJDK.Misc.dll - -baseaddress:0x5B880000 + -baseaddress:0x5B8B0000 -resource:com/sun/servicetag/resources/javase_5_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties -resource:com/sun/servicetag/resources/javase_6_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties -resource:com/sun/servicetag/resources/javase_7_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties @@ -993,7 +994,7 @@ assembly.class } { -out:IKVM.OpenJDK.Naming.dll - -baseaddress:0x5B9A0000 + -baseaddress:0x5B9D0000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/ldap/jndiprovider.properties -resource:META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor=@OPENJDK7@/jdk/src/share/classes/sun/net/spi/nameservice/dns/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor sun/net/dns/*.class @@ -1019,7 +1020,7 @@ assembly.class } { -out:IKVM.OpenJDK.Jdbc.dll - -baseaddress:0x5BAF0000 + -baseaddress:0x5BB20000 -resource:META-INF/services/java.sql.Driver=resources/META-INF/services/java.sql.Driver -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/rowset/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/sql/* @@ -1037,7 +1038,7 @@ assembly.class } { -out:IKVM.OpenJDK.Remoting.dll - -baseaddress:0x5BC40000 + -baseaddress:0x5BC70000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/rmi/* @OPENJDK7@/build/linux-amd64/classes/sun/rmi/registry/*.class @OPENJDK7@/build/linux-amd64/classes/sun/rmi/server/*.class @@ -1063,7 +1064,7 @@ assembly.class } { -out:IKVM.OpenJDK.Beans.dll - -baseaddress:0x5BD60000 + -baseaddress:0x5BD90000 @OPENJDK7@/build/linux-amd64/impsrc/com/sun/activation/registries/*.class @OPENJDK7@/build/linux-amd64/impsrc/javax/activation/*.class @OPENJDK7@/jdk/src/share/classes/com/sun/beans/*.class @@ -1076,7 +1077,7 @@ assembly.class } { -out:IKVM.OpenJDK.Media.dll - -baseaddress:0x5BE20000 + -baseaddress:0x5BE50000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.print.* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.sound.* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/imageio/plugins/common/iio-plugin.properties diff --git a/openjdk/sun/misc/Unsafe.java b/openjdk/sun/misc/Unsafe.java index 104b4c0d..748e3b02 100644 --- a/openjdk/sun/misc/Unsafe.java +++ b/openjdk/sun/misc/Unsafe.java @@ -46,7 +46,7 @@ public final class Unsafe private Unsafe() { } - @ikvm.internal.HasCallerID + @sun.reflect.CallerSensitive public static Unsafe getUnsafe() { if(ikvm.internal.CallerID.getCallerID().getCallerClassLoader() != null) diff --git a/openjdk/sun/reflect/Reflection.java b/openjdk/sun/reflect/Reflection.java index 5d237a63..6cff5746 100644 --- a/openjdk/sun/reflect/Reflection.java +++ b/openjdk/sun/reflect/Reflection.java @@ -63,6 +63,14 @@ public class Reflection { methodFilterMap.put(sun.misc.Unsafe.class, new String[] {"getUnsafe"}); } + /** Returns the class of the caller of the method calling this method, + ignoring frames associated with java.lang.reflect.Method.invoke() + and its implementation. */ + @CallerSensitive + public static Class getCallerClass() { + return getCallerClass(2); + } + /** Returns the class of the method <code>realFramesToSkip</code> frames up the stack (zero-based), ignoring frames associated with java.lang.reflect.Method.invoke() and its implementation. @@ -72,6 +80,7 @@ public class Reflection { java.lang.reflect.Method.invoke() and its implementation are completely ignored and do not count toward the number of "real" frames skipped. */ + @CallerSensitive public static native Class getCallerClass(int realFramesToSkip); /** Retrieves the access flags written to the class file. For diff --git a/runtime/ClassFile.cs b/runtime/ClassFile.cs index e90b3c27..db684117 100644 --- a/runtime/ClassFile.cs +++ b/runtime/ClassFile.cs @@ -65,7 +65,7 @@ namespace IKVM.Internal private const ushort FLAG_MASK_MAJORVERSION = 0xFF; private const ushort FLAG_MASK_DEPRECATED = 0x100; private const ushort FLAG_MASK_INTERNAL = 0x200; - private const ushort FLAG_HAS_CALLERID = 0x400; + private const ushort FLAG_CALLERSENSITIVE = 0x400; private ConstantPoolItemClass[] interfaces; private Field[] fields; private Method[] methods; @@ -2655,6 +2655,15 @@ namespace IKVM.Internal goto default; } annotations = ReadAnnotations(br, classFile, utf8_cp); +#if STATIC_COMPILER + foreach(object[] annot in annotations) + { + if(annot[1].Equals("Lsun/reflect/CallerSensitive;")) + { + flags |= FLAG_CALLERSENSITIVE; + } + } +#endif break; case "RuntimeVisibleParameterAnnotations": { @@ -2722,10 +2731,6 @@ namespace IKVM.Internal flags |= FLAG_MASK_INTERNAL; } } - if(annot[1].Equals("Likvm/internal/HasCallerID;")) - { - flags |= FLAG_HAS_CALLERID; - } if(annot[1].Equals("Likvm/lang/DllExport;")) { string name = null; @@ -2844,14 +2849,15 @@ namespace IKVM.Internal } } - // for use by ikvmc only - internal bool HasCallerIDAnnotation +#if STATIC_COMPILER + internal bool IsCallerSensitive { get { - return (flags & FLAG_HAS_CALLERID) != 0; + return (flags & FLAG_CALLERSENSITIVE) != 0; } } +#endif internal string[] ExceptionsAttribute { diff --git a/runtime/DynamicTypeWrapper.cs b/runtime/DynamicTypeWrapper.cs index 328c2f1d..5861d0c0 100644 --- a/runtime/DynamicTypeWrapper.cs +++ b/runtime/DynamicTypeWrapper.cs @@ -501,13 +501,14 @@ namespace IKVM.Internal { flags |= MemberFlags.InternalAccess; } - // we only support HasCallerID instance methods on final types, because we don't support interface stubs with CallerID - if (m.HasCallerIDAnnotation - && (m.IsStatic || classFile.IsFinal) - && CoreClasses.java.lang.Object.Wrapper.InternalsVisibleTo(wrapper)) +#if STATIC_COMPILER + if (m.IsCallerSensitive + && CoreClasses.ikvm.@internal.CallerID.Wrapper.InternalsVisibleTo(wrapper) // we only look at CallerSensitive when we're compiling the core class library + && SupportsCallerID(m)) { flags |= MemberFlags.CallerID; } +#endif if (wrapper.IsGhost) { methods[i] = new GhostMethodWrapper(wrapper, m.Name, m.Signature, null, null, null, null, m.Modifiers, flags); @@ -575,6 +576,63 @@ namespace IKVM.Internal wrapper.SetFields(fields); } +#if STATIC_COMPILER + private bool SupportsCallerID(ClassFile.Method method) + { + if ((classFile.Name == "sun.reflect.Reflection" && method.Name == "getCallerClass") + || (classFile.Name == "java.util.logging.Logger" && method.Name == "findResourceBundleFromStack")) + { + // ignore CallerSensitive on methods that don't need CallerID parameter + return false; + } + else if (method.IsStatic) + { + return true; + } + else if ((classFile.IsFinal || classFile.Name == "java.lang.Runtime" || classFile.Name == "java.io.ObjectStreamClass") + && wrapper.BaseTypeWrapper.GetMethodWrapper(method.Name, method.Signature, true) == null + && !HasInterfaceMethod(wrapper, method.Name, method.Signature)) + { + // We only support CallerID instance methods on final or effectively final types, + // because we don't support interface stubs with CallerID. + // We also don't support a CallerID method overriding a method or implementing an interface. + return true; + } + else if (RequiresDynamicReflectionCallerClass(classFile.Name, method.Name, method.Signature)) + { + // We don't support CallerID for virtual methods that can be overridden or implement an interface, + // so these methods will do a dynamic stack walk if when Reflection.getCallerClass() is used. + return false; + } + else + { + // If we end up here, we either have to add support or add them to the white-list in the above clause + // to allow them to fall back to dynamic stack walking. + StaticCompiler.IssueMessage(Message.CallerSensitiveOnUnsupportedMethod, classFile.Name, method.Name, method.Signature); + return false; + } + } + + private static bool HasInterfaceMethod(TypeWrapper tw, string name, string signature) + { + for (; tw != null; tw = tw.BaseTypeWrapper) + { + foreach (TypeWrapper iface in tw.Interfaces) + { + if (iface.GetMethodWrapper(name, signature, false) != null) + { + return true; + } + if (HasInterfaceMethod(iface, name, signature)) + { + return true; + } + } + } + return false; + } +#endif + internal void CreateStep2() { #if STATIC_COMPILER @@ -6401,6 +6459,12 @@ namespace IKVM.Internal && (fw.IsPublic || (fw.IsProtected && !this.IsFinal)) && (fw.FieldTypeWrapper.IsUnloadable || fw.FieldTypeWrapper.IsAccessibleFrom(this) || fw.FieldTypeWrapper.InternalsVisibleTo(this))); } + + internal static bool RequiresDynamicReflectionCallerClass(string classFile, string method, string signature) + { + return (classFile == "java.lang.ClassLoader" && method == "getParent" && signature == "()Ljava.lang.ClassLoader;") + || (classFile == "java.lang.Thread" && method == "getContextClassLoader" && signature == "()Ljava.lang.ClassLoader;"); + } #endif } diff --git a/runtime/intrinsics.cs b/runtime/intrinsics.cs index 7099a7a8..402969d7 100644 --- a/runtime/intrinsics.cs +++ b/runtime/intrinsics.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2008-2012 Jeroen Frijters + Copyright (C) 2008-2013 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -192,10 +192,9 @@ namespace IKVM.Internal #if STATIC_COMPILER // String_toCharArray relies on globals, which aren't usable in dynamic mode intrinsics.Add(new IntrinsicKey("java.lang.String", "toCharArray", "()[C"), String_toCharArray); -#endif - intrinsics.Add(new IntrinsicKey("sun.reflect.Reflection", "getCallerClass", "(I)Ljava.lang.Class;"), Reflection_getCallerClass); - intrinsics.Add(new IntrinsicKey("java.lang.ClassLoader", "getCallerClassLoader", "()Ljava.lang.ClassLoader;"), ClassLoader_getCallerClassLoader); + intrinsics.Add(new IntrinsicKey("sun.reflect.Reflection", "getCallerClass", "()Ljava.lang.Class;"), Reflection_getCallerClass); intrinsics.Add(new IntrinsicKey("ikvm.internal.CallerID", "getCallerID", "()Likvm.internal.CallerID;"), CallerID_getCallerID); +#endif intrinsics.Add(new IntrinsicKey("ikvm.runtime.Util", "getInstanceTypeFromClass", "(Ljava.lang.Class;)Lcli.System.Type;"), Util_getInstanceTypeFromClass); #if STATIC_COMPILER // this only applies to the core class library, so makes no sense in dynamic mode @@ -512,44 +511,35 @@ namespace IKVM.Internal ilgen.Emit(OpCodes.Ldtoken, fb); ilgen.Emit(OpCodes.Call, JVM.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers)).GetMethod("InitializeArray", new Type[] { Types.Array, JVM.Import(typeof(RuntimeFieldHandle)) })); } -#endif private static bool Reflection_getCallerClass(EmitIntrinsicContext eic) { - if (eic.Caller.HasCallerID - && eic.MatchRange(-1, 2) - && eic.Match(-1, NormalizedByteCode.__iconst, 2)) + if (eic.Caller.HasCallerID) { - eic.Emitter.Emit(OpCodes.Pop); int arg = eic.Caller.GetParametersForDefineMethod().Length - 1; if (!eic.Caller.IsStatic) { arg++; } eic.Emitter.EmitLdarg(arg); - MethodWrapper mw = CoreClasses.ikvm.@internal.CallerID.Wrapper.GetMethodWrapper("getCallerClass", "()Ljava.lang.Class;", false); - mw.Link(); - mw.EmitCallvirt(eic.Emitter); - return true; - } - return false; - } - - private static bool ClassLoader_getCallerClassLoader(EmitIntrinsicContext eic) - { - if (eic.Caller.HasCallerID) - { - int arg = eic.Caller.GetParametersForDefineMethod().Length - 1; - if (!eic.Caller.IsStatic) + MethodWrapper mw; + if (MatchInvokeStatic(eic, 1, "java.lang.ClassLoader", "getClassLoader", "(Ljava.lang.Class;)Ljava.lang.ClassLoader;")) { - arg++; + eic.PatchOpCode(1, NormalizedByteCode.__nop); + mw = CoreClasses.ikvm.@internal.CallerID.Wrapper.GetMethodWrapper("getCallerClassLoader", "()Ljava.lang.ClassLoader;", false); + } + else + { + mw = CoreClasses.ikvm.@internal.CallerID.Wrapper.GetMethodWrapper("getCallerClass", "()Ljava.lang.Class;", false); } - eic.Emitter.EmitLdarg(arg); - MethodWrapper mw = CoreClasses.ikvm.@internal.CallerID.Wrapper.GetMethodWrapper("getCallerClassLoader", "()Ljava.lang.ClassLoader;", false); mw.Link(); mw.EmitCallvirt(eic.Emitter); return true; } + else if (!DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature)) + { + StaticCompiler.IssueMessage(Message.ReflectionCallerClassRequiresCallerID, eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature); + } return false; } @@ -567,14 +557,10 @@ namespace IKVM.Internal } else { -#if STATIC_COMPILER throw new FatalCompilerErrorException(Message.CallerIDRequiresHasCallerIDAnnotation); -#else - JVM.CriticalFailure("CallerID.getCallerID() requires a HasCallerID annotation", null); - return false; -#endif } } +#endif private static bool Util_getInstanceTypeFromClass(EmitIntrinsicContext eic) { @@ -976,7 +962,17 @@ namespace IKVM.Internal private static bool MatchInvokeVirtual(EmitIntrinsicContext eic, ref Instruction instr, string clazz, string name, string sig) { - if (instr.NormalizedOpCode == NormalizedByteCode.__invokevirtual) + return MatchInvoke(eic, ref instr, NormalizedByteCode.__invokevirtual, clazz, name, sig); + } + + private static bool MatchInvokeStatic(EmitIntrinsicContext eic, int offset, string clazz, string name, string sig) + { + return MatchInvoke(eic, ref eic.Code[eic.OpcodeIndex + offset], NormalizedByteCode.__invokestatic, clazz, name, sig); + } + + private static bool MatchInvoke(EmitIntrinsicContext eic, ref Instruction instr, NormalizedByteCode opcode, string clazz, string name, string sig) + { + if (instr.NormalizedOpCode == opcode) { ClassFile.ConstantPoolItemMI method = eic.ClassFile.GetMethodref(instr.Arg1); return method.Class == clazz |