8230043: Lazily load libverify
8230140: Remove unused mutex and monitor declarations
Reviewed-by: hseigel, erikj, alanb, dholmes
--- a/make/lib/CoreLibraries.gmk Mon Oct 07 16:44:12 2019 +0200
+++ b/make/lib/CoreLibraries.gmk Mon Oct 07 16:55:24 2019 +0200
@@ -23,8 +23,6 @@
# questions.
#
-WIN_VERIFY_LIB := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libverify/verify.lib
-
# Hook to include the corresponding custom file, if present.
$(eval $(call IncludeCustomExtension, lib/CoreLibraries.gmk))
@@ -110,14 +108,14 @@
LDFLAGS_macosx := -L$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/, \
LDFLAGS_windows := -delayload:shell32.dll, \
LIBS := $(BUILD_LIBFDLIBM_TARGET), \
- LIBS_unix := -ljvm -lverify, \
+ LIBS_unix := -ljvm, \
LIBS_linux := $(LIBDL), \
LIBS_solaris := -lsocket -lnsl -lscf $(LIBDL), \
LIBS_aix := $(LIBDL) $(LIBM),\
LIBS_macosx := -framework CoreFoundation \
-framework Foundation \
-framework SystemConfiguration, \
- LIBS_windows := jvm.lib $(WIN_VERIFY_LIB) \
+ LIBS_windows := jvm.lib \
shell32.lib delayimp.lib \
advapi32.lib version.lib, \
))
--- a/src/hotspot/share/classfile/verifier.cpp Mon Oct 07 16:44:12 2019 +0200
+++ b/src/hotspot/share/classfile/verifier.cpp Mon Oct 07 16:55:24 2019 +0200
@@ -63,29 +63,39 @@
#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52
#define MAX_ARRAY_DIMENSIONS 255
-// Access to external entry for VerifyClassCodes - old byte code verifier
+// Access to external entry for VerifyClassForMajorVersion - old byte code verifier
extern "C" {
- typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint);
- typedef jboolean (*verify_byte_codes_fn_new_t)(JNIEnv *, jclass, char *, jint, jint);
+ typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint, jint);
}
-static void* volatile _verify_byte_codes_fn = NULL;
+static verify_byte_codes_fn_t volatile _verify_byte_codes_fn = NULL;
+
+static verify_byte_codes_fn_t verify_byte_codes_fn() {
-static volatile jint _is_new_verify_byte_codes_fn = (jint) true;
+ if (_verify_byte_codes_fn != NULL)
+ return _verify_byte_codes_fn;
+
+ MutexLocker locker(Verify_lock);
+
+ if (_verify_byte_codes_fn != NULL)
+ return _verify_byte_codes_fn;
-static void* verify_byte_codes_fn() {
- if (OrderAccess::load_acquire(&_verify_byte_codes_fn) == NULL) {
- void *lib_handle = os::native_java_library();
- void *func = os::dll_lookup(lib_handle, "VerifyClassCodesForMajorVersion");
- OrderAccess::release_store(&_verify_byte_codes_fn, func);
- if (func == NULL) {
- _is_new_verify_byte_codes_fn = false;
- func = os::dll_lookup(lib_handle, "VerifyClassCodes");
- OrderAccess::release_store(&_verify_byte_codes_fn, func);
- }
- }
- return (void*)_verify_byte_codes_fn;
+ // Load verify dll
+ char buffer[JVM_MAXPATHLEN];
+ char ebuf[1024];
+ if (!os::dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"))
+ return NULL; // Caller will throw VerifyError
+
+ void *lib_handle = os::dll_load(buffer, ebuf, sizeof(ebuf));
+ if (lib_handle == NULL)
+ return NULL; // Caller will throw VerifyError
+
+ void *fn = os::dll_lookup(lib_handle, "VerifyClassForMajorVersion");
+ if (fn == NULL)
+ return NULL; // Caller will throw VerifyError
+
+ return _verify_byte_codes_fn = CAST_TO_FN_PTR(verify_byte_codes_fn_t, fn);
}
@@ -282,7 +292,7 @@
JavaThread* thread = (JavaThread*)THREAD;
JNIEnv *env = thread->jni_environment();
- void* verify_func = verify_byte_codes_fn();
+ verify_byte_codes_fn_t verify_func = verify_byte_codes_fn();
if (verify_func == NULL) {
jio_snprintf(message, message_len, "Could not link verifier");
@@ -301,16 +311,7 @@
// ThreadToNativeFromVM takes care of changing thread_state, so safepoint
// code knows that we have left the VM
- if (_is_new_verify_byte_codes_fn) {
- verify_byte_codes_fn_new_t func =
- CAST_TO_FN_PTR(verify_byte_codes_fn_new_t, verify_func);
- result = (*func)(env, cls, message, (int)message_len,
- klass->major_version());
- } else {
- verify_byte_codes_fn_t func =
- CAST_TO_FN_PTR(verify_byte_codes_fn_t, verify_func);
- result = (*func)(env, cls, message, (int)message_len);
- }
+ result = (*verify_func)(env, cls, message, (int)message_len, klass->major_version());
}
JNIHandles::destroy_local(cls);
--- a/src/hotspot/share/include/jvm.h Mon Oct 07 16:44:12 2019 +0200
+++ b/src/hotspot/share/include/jvm.h Mon Oct 07 16:55:24 2019 +0200
@@ -1044,19 +1044,6 @@
#include "classfile_constants.h"
/*
- * A function defined by the byte-code verifier and called by the VM.
- * This is not a function implemented in the VM.
- *
- * Returns JNI_FALSE if verification fails. A detailed error message
- * will be places in msg_buf, whose length is specified by buf_len.
- */
-typedef jboolean (*verifier_fn_t)(JNIEnv *env,
- jclass cb,
- char * msg_buf,
- jint buf_len);
-
-
-/*
* Support for a VM-independent class format checker.
*/
typedef struct {
@@ -1086,28 +1073,6 @@
typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str);
-typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b);
-
-/* This is the function defined in libjava.so that performs class
- * format checks. This functions fills in size information about
- * the class file and returns:
- *
- * 0: good
- * -1: out of memory
- * -2: bad format
- * -3: unsupported version
- * -4: bad class name
- */
-
-typedef jint (*check_format_fn_t)(char *class_name,
- unsigned char *data,
- unsigned int data_size,
- class_size_info *class_size,
- char *message_buffer,
- jint buffer_length,
- jboolean measure_only,
- jboolean check_relaxed);
-
#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \
JVM_ACC_FINAL | \
JVM_ACC_SUPER | \
--- a/src/hotspot/share/runtime/mutexLocker.cpp Mon Oct 07 16:44:12 2019 +0200
+++ b/src/hotspot/share/runtime/mutexLocker.cpp Mon Oct 07 16:55:24 2019 +0200
@@ -66,7 +66,6 @@
Mutex* RetData_lock = NULL;
Monitor* VMOperationQueue_lock = NULL;
Monitor* VMOperationRequest_lock = NULL;
-Monitor* SerializePage_lock = NULL;
Monitor* Threads_lock = NULL;
Mutex* NonJavaThreadsList_lock = NULL;
Mutex* NonJavaThreadsListSync_lock = NULL;
@@ -118,6 +117,7 @@
Monitor* Service_lock = NULL;
Monitor* PeriodicTask_lock = NULL;
Monitor* RedefineClasses_lock = NULL;
+Mutex* Verify_lock = NULL;
#if INCLUDE_JFR
Mutex* JfrStacktrace_lock = NULL;
@@ -298,6 +298,7 @@
def(CompileThread_lock , PaddedMonitor, nonleaf+5, false, _safepoint_check_always);
def(PeriodicTask_lock , PaddedMonitor, nonleaf+5, true, _safepoint_check_always);
def(RedefineClasses_lock , PaddedMonitor, nonleaf+5, true, _safepoint_check_always);
+ def(Verify_lock , PaddedMutex, nonleaf+5, true, _safepoint_check_always);
if (WhiteBoxAPI) {
def(Compilation_lock , PaddedMonitor, leaf, false, _safepoint_check_never);
--- a/src/hotspot/share/runtime/mutexLocker.hpp Mon Oct 07 16:44:12 2019 +0200
+++ b/src/hotspot/share/runtime/mutexLocker.hpp Mon Oct 07 16:55:24 2019 +0200
@@ -103,7 +103,6 @@
extern Mutex* RawMonitor_lock;
extern Mutex* PerfDataMemAlloc_lock; // a lock on the allocator for PerfData memory for performance data
extern Mutex* PerfDataManager_lock; // a long on access to PerfDataManager resources
-extern Mutex* ParkerFreeList_lock;
extern Mutex* OopMapCacheAlloc_lock; // protects allocation of oop_map caches
extern Mutex* FreeList_lock; // protects the free region list during safepoints
@@ -114,6 +113,7 @@
extern Monitor* Service_lock; // a lock used for service thread operation
extern Monitor* PeriodicTask_lock; // protects the periodic task structure
extern Monitor* RedefineClasses_lock; // locks classes from parallel redefinition
+extern Mutex* Verify_lock; // synchronize initialization of verify library
extern Monitor* ThreadsSMRDelete_lock; // Used by ThreadsSMRSupport to take pressure off the Threads_lock
extern Mutex* ThreadIdTableCreate_lock; // Used by ThreadIdTable to lazily create the thread id table
extern Mutex* SharedDecoder_lock; // serializes access to the decoder during normal (not error reporting) use
--- a/src/hotspot/share/runtime/os.cpp Mon Oct 07 16:44:12 2019 +0200
+++ b/src/hotspot/share/runtime/os.cpp Mon Oct 07 16:55:24 2019 +0200
@@ -536,14 +536,6 @@
char buffer[JVM_MAXPATHLEN];
char ebuf[1024];
- // Try to load verify dll first. In 1.3 java dll depends on it and is not
- // always able to find it when the loading executable is outside the JDK.
- // In order to keep working with 1.2 we ignore any loading errors.
- if (dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),
- "verify")) {
- dll_load(buffer, ebuf, sizeof(ebuf));
- }
-
// Load java dll
if (dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),
"java")) {
--- a/src/java.base/share/native/libjava/Class.c Mon Oct 07 16:44:12 2019 +0200
+++ b/src/java.base/share/native/libjava/Class.c Mon Oct 07 16:55:24 2019 +0200
@@ -35,12 +35,9 @@
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
+#include "check_classname.h"
#include "java_lang_Class.h"
-/* defined in libverify.so/verify.dll (src file common/check_format.c) */
-extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed);
-extern jboolean VerifyFixClassname(char *utf_name);
-
#define OBJ "Ljava/lang/Object;"
#define CLS "Ljava/lang/Class;"
#define CPL "Ljdk/internal/reflect/ConstantPool;"
@@ -123,14 +120,14 @@
}
(*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);
- if (VerifyFixClassname(clname) == JNI_TRUE) {
+ if (verifyFixClassname(clname) == JNI_TRUE) {
/* slashes present in clname, use name b4 translation for exception */
(*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);
JNU_ThrowClassNotFoundException(env, clname);
goto done;
}
- if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
+ if (!verifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
JNU_ThrowClassNotFoundException(env, clname);
goto done;
}
--- a/src/java.base/share/native/libjava/ClassLoader.c Mon Oct 07 16:44:12 2019 +0200
+++ b/src/java.base/share/native/libjava/ClassLoader.c Mon Oct 07 16:55:24 2019 +0200
@@ -30,14 +30,11 @@
#include "jni_util.h"
#include "jlong.h"
#include "jvm.h"
+#include "check_classname.h"
#include "java_lang_ClassLoader.h"
#include "java_lang_ClassLoader_NativeLibrary.h"
#include <string.h>
-/* defined in libverify.so/verify.dll (src file common/check_format.c) */
-extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed);
-extern jboolean VerifyFixClassname(char *utf_name);
-
static JNINativeMethod methods[] = {
{"retrieveDirectives", "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
};
@@ -120,7 +117,7 @@
if (utfName == NULL) {
goto free_body;
}
- VerifyFixClassname(utfName);
+ fixClassname(utfName);
} else {
utfName = NULL;
}
@@ -185,7 +182,7 @@
JNU_ThrowOutOfMemoryError(env, NULL);
return result;
}
- VerifyFixClassname(utfName);
+ fixClassname(utfName);
} else {
utfName = NULL;
}
@@ -231,9 +228,9 @@
JNU_ThrowOutOfMemoryError(env, NULL);
return NULL;
}
- VerifyFixClassname(clname);
+ fixClassname(clname);
- if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
+ if (!verifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
goto done;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libjava/check_classname.c Mon Oct 07 16:55:24 2019 +0200
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1997, 2019, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "jni.h"
+#include "jvm.h"
+#include "check_classname.h"
+
+typedef unsigned short unicode;
+
+static char *
+skip_over_fieldname(char *name, jboolean slash_okay,
+ unsigned int len);
+static char *
+skip_over_field_signature(char *name, jboolean void_okay,
+ unsigned int len);
+
+/*
+ * Return non-zero if the character is a valid in JVM class name, zero
+ * otherwise. The only characters currently disallowed from JVM class
+ * names are given in the table below:
+ *
+ * Character Hex Decimal
+ * '.' 0x2e 46
+ * '/' 0x2f 47
+ * ';' 0x3b 59
+ * '[' 0x5b 91
+ *
+ * (Method names have further restrictions dealing with the '<' and
+ * '>' characters.)
+ */
+static int isJvmIdentifier(unicode ch) {
+ if( ch > 91 || ch < 46 )
+ return 1; /* Lowercase ASCII letters are > 91 */
+ else { /* 46 <= ch <= 91 */
+ if (ch <= 90 && ch >= 60) {
+ return 1; /* Uppercase ASCII recognized here */
+ } else { /* ch == 91 || 46 <= ch <= 59 */
+ if (ch == 91 || ch == 59 || ch <= 47)
+ return 0;
+ else
+ return 1;
+ }
+ }
+}
+
+static unicode
+next_utf2unicode(char **utfstring_ptr, int * valid)
+{
+ unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
+ unsigned char ch, ch2, ch3;
+ int length = 1; /* default length */
+ unicode result = 0x80; /* default bad result; */
+ *valid = 1;
+ switch ((ch = ptr[0]) >> 4) {
+ default:
+ result = ch;
+ break;
+
+ case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
+ /* Shouldn't happen. */
+ *valid = 0;
+ break;
+
+ case 0xC: case 0xD:
+ /* 110xxxxx 10xxxxxx */
+ if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+ unsigned char high_five = ch & 0x1F;
+ unsigned char low_six = ch2 & 0x3F;
+ result = (high_five << 6) + low_six;
+ length = 2;
+ }
+ break;
+
+ case 0xE:
+ /* 1110xxxx 10xxxxxx 10xxxxxx */
+ if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+ if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
+ unsigned char high_four = ch & 0x0f;
+ unsigned char mid_six = ch2 & 0x3f;
+ unsigned char low_six = ch3 & 0x3f;
+ result = (((high_four << 6) + mid_six) << 6) + low_six;
+ length = 3;
+ } else {
+ length = 2;
+ }
+ }
+ break;
+ } /* end of switch */
+
+ *utfstring_ptr = (char *)(ptr + length);
+ return result;
+}
+
+/* Take pointer to a string. Skip over the longest part of the string that
+ * could be taken as a fieldname. Allow '/' if slash_okay is JNI_TRUE.
+ *
+ * Return a pointer to just past the fieldname. Return NULL if no fieldname
+ * at all was found, or in the case of slash_okay being true, we saw
+ * consecutive slashes (meaning we were looking for a qualified path but
+ * found something that was badly-formed).
+ */
+static char *
+skip_over_fieldname(char *name, jboolean slash_okay,
+ unsigned int length)
+{
+ char *p;
+ unicode ch;
+ unicode last_ch = 0;
+ int valid = 1;
+ /* last_ch == 0 implies we are looking at the first char. */
+ for (p = name; p != name + length; last_ch = ch) {
+ char *old_p = p;
+ ch = *p;
+ if (ch < 128) {
+ p++;
+ if (isJvmIdentifier(ch)) {
+ continue;
+ }
+ } else {
+ char *tmp_p = p;
+ ch = next_utf2unicode(&tmp_p, &valid);
+ if (valid == 0)
+ return 0;
+ p = tmp_p;
+ if (isJvmIdentifier(ch)) {
+ continue;
+ }
+ }
+
+ if (slash_okay && ch == '/' && last_ch) {
+ if (last_ch == '/') {
+ return 0; /* Don't permit consecutive slashes */
+ }
+ } else if (ch == '_' || ch == '$') {
+ } else {
+ return last_ch ? old_p : 0;
+ }
+ }
+ return last_ch ? p : 0;
+}
+
+/* Take pointer to a string. Skip over the longest part of the string that
+ * could be taken as a field signature. Allow "void" if void_okay.
+ *
+ * Return a pointer to just past the signature. Return NULL if no legal
+ * signature is found.
+ */
+
+static char *
+skip_over_field_signature(char *name, jboolean void_okay,
+ unsigned int length)
+{
+ unsigned int array_dim = 0;
+ for (;length > 0;) {
+ switch (name[0]) {
+ case JVM_SIGNATURE_VOID:
+ if (!void_okay) return 0;
+ /* FALL THROUGH */
+ case JVM_SIGNATURE_BOOLEAN:
+ case JVM_SIGNATURE_BYTE:
+ case JVM_SIGNATURE_CHAR:
+ case JVM_SIGNATURE_SHORT:
+ case JVM_SIGNATURE_INT:
+ case JVM_SIGNATURE_FLOAT:
+ case JVM_SIGNATURE_LONG:
+ case JVM_SIGNATURE_DOUBLE:
+ return name + 1;
+
+ case JVM_SIGNATURE_CLASS: {
+ /* Skip over the classname, if one is there. */
+ char *p =
+ skip_over_fieldname(name + 1, JNI_TRUE, --length);
+ /* The next character better be a semicolon. */
+ if (p && p - name - 1 > 0 && p[0] == ';')
+ return p + 1;
+ return 0;
+ }
+
+ case JVM_SIGNATURE_ARRAY:
+ array_dim++;
+ /* JVMS 2nd ed. 4.10 */
+ /* The number of dimensions in an array is limited to 255 ... */
+ if (array_dim > 255) {
+ return 0;
+ }
+ /* The rest of what's there better be a legal signature. */
+ name++;
+ length--;
+ void_okay = JNI_FALSE;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+
+/* Determine if the specified name is legal
+ * UTF name for a classname.
+ *
+ * Note that this routine expects the internal form of qualified classes:
+ * the dots should have been replaced by slashes.
+ */
+jboolean verifyClassname(char *name, jboolean allowArrayClass)
+{
+ size_t s = strlen(name);
+ assert(s <= UINT_MAX);
+ unsigned int length = (unsigned int)s;
+ char *p;
+
+ if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
+ if (!allowArrayClass) {
+ return JNI_FALSE;
+ } else {
+ /* Everything that's left better be a field signature */
+ p = skip_over_field_signature(name, JNI_FALSE, length);
+ }
+ } else {
+ /* skip over the fieldname. Slashes are okay */
+ p = skip_over_fieldname(name, JNI_TRUE, length);
+ }
+ return (p != 0 && p - name == (ptrdiff_t)length);
+}
+
+/*
+ * Translates '.' to '/'. Returns JNI_TRUE if any / were present.
+ */
+jboolean verifyFixClassname(char *name)
+{
+ char *p = name;
+ jboolean slashesFound = JNI_FALSE;
+ int valid = 1;
+
+ while (valid != 0 && *p != '\0') {
+ if (*p == '/') {
+ slashesFound = JNI_TRUE;
+ p++;
+ } else if (*p == '.') {
+ *p++ = '/';
+ } else {
+ next_utf2unicode(&p, &valid);
+ }
+ }
+
+ return slashesFound && valid != 0;
+}
+
+/*
+ * Translates '.' to '/'.
+ */
+void fixClassname(char *name)
+{
+ char *p = name;
+ int valid = 1;
+
+ while (valid != 0 && *p != '\0') {
+ if (*p == '.') {
+ *p++ = '/';
+ } else {
+ next_utf2unicode(&p, &valid);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libjava/check_classname.h Mon Oct 07 16:55:24 2019 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+
+/*
+ * Class name checking methods
+ */
+
+jboolean verifyClassname(char *name, jboolean allowArrayClass);
+jboolean verifyFixClassname(char *name);
+void fixClassname(char *name);
--- a/src/java.base/share/native/libjava/verify_stub.c Mon Oct 07 16:44:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 1999, 2003, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * The real verifier now lives in libverifier.so/verifier.dll.
- *
- * This dummy exists so that HotSpot will run with the new
- * libjava.so/java.dll which is where is it accustomed to finding the
- * verifier.
- */
-
-#include "jni.h"
-
-struct struct_class_size_info;
-typedef struct struct_class_size_info class_size_info;
-
-
-JNIIMPORT jboolean
-VerifyClass(JNIEnv *env, jclass cb, char *buffer, jint len);
-
-JNIIMPORT jboolean
-VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *buffer, jint len,
- jint major_version);
-
-JNIEXPORT jboolean
-VerifyClassCodes(JNIEnv *env, jclass cb, char *buffer, jint len)
-{
- return VerifyClass(env, cb, buffer, len);
-}
-
-JNIEXPORT jboolean
-VerifyClassCodesForMajorVersion(JNIEnv *env, jclass cb, char *buffer,
- jint len, jint major_version)
-{
- return VerifyClassForMajorVersion(env, cb, buffer, len, major_version);
-}
--- a/src/java.base/share/native/libverify/check_code.c Mon Oct 07 16:44:12 2019 +0200
+++ b/src/java.base/share/native/libverify/check_code.c Mon Oct 07 16:55:24 2019 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, 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
@@ -31,9 +31,6 @@
Exported function:
jboolean
- VerifyClass(JNIEnv *env, jclass cb, char *message_buffer,
- jint buffer_length)
- jboolean
VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *message_buffer,
jint buffer_length, jint major_version)
@@ -910,20 +907,6 @@
return result;
}
-#define OLD_FORMAT_MAX_MAJOR_VERSION 48
-
-JNIEXPORT jboolean
-VerifyClass(JNIEnv *env, jclass cb, char *buffer, jint len)
-{
- static int warned = 0;
- if (!warned) {
- jio_fprintf(stdout, "Warning! An old version of jvm is used. This is not supported.\n");
- warned = 1;
- }
- return VerifyClassForMajorVersion(env, cb, buffer, len,
- OLD_FORMAT_MAX_MAJOR_VERSION);
-}
-
static void
verify_field(context_type *context, jclass cb, int field_index)
{
--- a/src/java.base/share/native/libverify/check_format.c Mon Oct 07 16:44:12 2019 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 1997, 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <assert.h>
-#include <limits.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "jni.h"
-#include "jvm.h"
-
-typedef unsigned short unicode;
-
-static char *
-skip_over_fieldname(char *name, jboolean slash_okay,
- unsigned int len);
-static char *
-skip_over_field_signature(char *name, jboolean void_okay,
- unsigned int len);
-
-/*
- * Return non-zero if the character is a valid in JVM class name, zero
- * otherwise. The only characters currently disallowed from JVM class
- * names are given in the table below:
- *
- * Character Hex Decimal
- * '.' 0x2e 46
- * '/' 0x2f 47
- * ';' 0x3b 59
- * '[' 0x5b 91
- *
- * (Method names have further restrictions dealing with the '<' and
- * '>' characters.)
- */
-static int isJvmIdentifier(unicode ch) {
- if( ch > 91 || ch < 46 )
- return 1; /* Lowercase ASCII letters are > 91 */
- else { /* 46 <= ch <= 91 */
- if (ch <= 90 && ch >= 60) {
- return 1; /* Uppercase ASCII recognized here */
- } else { /* ch == 91 || 46 <= ch <= 59 */
- if (ch == 91 || ch == 59 || ch <= 47)
- return 0;
- else
- return 1;
- }
- }
-}
-
-static unicode
-next_utf2unicode(char **utfstring_ptr, int * valid)
-{
- unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
- unsigned char ch, ch2, ch3;
- int length = 1; /* default length */
- unicode result = 0x80; /* default bad result; */
- *valid = 1;
- switch ((ch = ptr[0]) >> 4) {
- default:
- result = ch;
- break;
-
- case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
- /* Shouldn't happen. */
- *valid = 0;
- break;
-
- case 0xC: case 0xD:
- /* 110xxxxx 10xxxxxx */
- if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
- unsigned char high_five = ch & 0x1F;
- unsigned char low_six = ch2 & 0x3F;
- result = (high_five << 6) + low_six;
- length = 2;
- }
- break;
-
- case 0xE:
- /* 1110xxxx 10xxxxxx 10xxxxxx */
- if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
- if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
- unsigned char high_four = ch & 0x0f;
- unsigned char mid_six = ch2 & 0x3f;
- unsigned char low_six = ch3 & 0x3f;
- result = (((high_four << 6) + mid_six) << 6) + low_six;
- length = 3;
- } else {
- length = 2;
- }
- }
- break;
- } /* end of switch */
-
- *utfstring_ptr = (char *)(ptr + length);
- return result;
-}
-
-/* Take pointer to a string. Skip over the longest part of the string that
- * could be taken as a fieldname. Allow '/' if slash_okay is JNI_TRUE.
- *
- * Return a pointer to just past the fieldname. Return NULL if no fieldname
- * at all was found, or in the case of slash_okay being true, we saw
- * consecutive slashes (meaning we were looking for a qualified path but
- * found something that was badly-formed).
- */
-static char *
-skip_over_fieldname(char *name, jboolean slash_okay,
- unsigned int length)
-{
- char *p;
- unicode ch;
- unicode last_ch = 0;
- int valid = 1;
- /* last_ch == 0 implies we are looking at the first char. */
- for (p = name; p != name + length; last_ch = ch) {
- char *old_p = p;
- ch = *p;
- if (ch < 128) {
- p++;
- if (isJvmIdentifier(ch)) {
- continue;
- }
- } else {
- char *tmp_p = p;
- ch = next_utf2unicode(&tmp_p, &valid);
- if (valid == 0)
- return 0;
- p = tmp_p;
- if (isJvmIdentifier(ch)) {
- continue;
- }
- }
-
- if (slash_okay && ch == '/' && last_ch) {
- if (last_ch == '/') {
- return 0; /* Don't permit consecutive slashes */
- }
- } else if (ch == '_' || ch == '$') {
- } else {
- return last_ch ? old_p : 0;
- }
- }
- return last_ch ? p : 0;
-}
-
-/* Take pointer to a string. Skip over the longest part of the string that
- * could be taken as a field signature. Allow "void" if void_okay.
- *
- * Return a pointer to just past the signature. Return NULL if no legal
- * signature is found.
- */
-
-static char *
-skip_over_field_signature(char *name, jboolean void_okay,
- unsigned int length)
-{
- unsigned int array_dim = 0;
- for (;length > 0;) {
- switch (name[0]) {
- case JVM_SIGNATURE_VOID:
- if (!void_okay) return 0;
- /* FALL THROUGH */
- case JVM_SIGNATURE_BOOLEAN:
- case JVM_SIGNATURE_BYTE:
- case JVM_SIGNATURE_CHAR:
- case JVM_SIGNATURE_SHORT:
- case JVM_SIGNATURE_INT:
- case JVM_SIGNATURE_FLOAT:
- case JVM_SIGNATURE_LONG:
- case JVM_SIGNATURE_DOUBLE:
- return name + 1;
-
- case JVM_SIGNATURE_CLASS: {
- /* Skip over the classname, if one is there. */
- char *p =
- skip_over_fieldname(name + 1, JNI_TRUE, --length);
- /* The next character better be a semicolon. */
- if (p && p - name - 1 > 0 && p[0] == ';')
- return p + 1;
- return 0;
- }
-
- case JVM_SIGNATURE_ARRAY:
- array_dim++;
- /* JVMS 2nd ed. 4.10 */
- /* The number of dimensions in an array is limited to 255 ... */
- if (array_dim > 255) {
- return 0;
- }
- /* The rest of what's there better be a legal signature. */
- name++;
- length--;
- void_okay = JNI_FALSE;
- break;
-
- default:
- return 0;
- }
- }
- return 0;
-}
-
-
-/* Used in java/lang/Class.c */
-/* Determine if the specified name is legal
- * UTF name for a classname.
- *
- * Note that this routine expects the internal form of qualified classes:
- * the dots should have been replaced by slashes.
- */
-JNIEXPORT jboolean
-VerifyClassname(char *name, jboolean allowArrayClass)
-{
- size_t s = strlen(name);
- assert(s <= UINT_MAX);
- unsigned int length = (unsigned int)s;
- char *p;
-
- if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
- if (!allowArrayClass) {
- return JNI_FALSE;
- } else {
- /* Everything that's left better be a field signature */
- p = skip_over_field_signature(name, JNI_FALSE, length);
- }
- } else {
- /* skip over the fieldname. Slashes are okay */
- p = skip_over_fieldname(name, JNI_TRUE, length);
- }
- return (p != 0 && p - name == (ptrdiff_t)length);
-}
-
-/*
- * Translates '.' to '/'. Returns JNI_TRUE is any / were present.
- */
-JNIEXPORT jboolean
-VerifyFixClassname(char *name)
-{
- char *p = name;
- jboolean slashesFound = JNI_FALSE;
- int valid = 1;
-
- while (valid != 0 && *p != '\0') {
- if (*p == '/') {
- slashesFound = JNI_TRUE;
- p++;
- } else if (*p == '.') {
- *p++ = '/';
- } else {
- next_utf2unicode(&p, &valid);
- }
- }
-
- return slashesFound && valid != 0;
-}
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java Mon Oct 07 16:44:12 2019 +0200
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java Mon Oct 07 16:55:24 2019 +0200
@@ -52,9 +52,8 @@
List<String> cmds = List.of("pmap");
Map<String, List<String>> expStrMap = new HashMap<>();
- expStrMap.put("pmap", List.of(
- "jvm", "java", "net", "nio",
- "jimage", "zip", "verify"));
+ expStrMap.put("pmap",
+ List.of("jvm", "java", "net", "nio", "jimage", "zip"));
test.run(theApp.getPid(), cmds, expStrMap, null);
} catch (SkippedException se) {