changeset 57304:2bea4bea7004

8234185: Cleanup usage of canonicalize function between libjava, hotspot and libinstrument Reviewed-by: dholmes, alanb, sspitsyn
author clanger
date Fri, 06 Dec 2019 14:13:10 +0100
parents cb2774f0e6eb
children 87fb3f5a499c
files src/hotspot/share/classfile/classLoader.cpp src/hotspot/share/include/jvm.h src/java.base/share/native/libjava/jdk_util.h src/java.base/share/native/libjava/jni_util.c src/java.base/unix/native/libjava/UnixFileSystem_md.c src/java.base/unix/native/libjava/canonicalize_md.c src/java.base/windows/native/libjava/canonicalize_md.c src/java.base/windows/native/libjava/io_util_md.h src/java.instrument/share/native/libinstrument/InvocationAdapter.c
diffstat 9 files changed, 54 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/classfile/classLoader.cpp	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/hotspot/share/classfile/classLoader.cpp	Fri Dec 06 14:13:10 2019 +0100
@@ -75,6 +75,8 @@
 
 // Entry point in java.dll for path canonicalization
 
+typedef int (*canonicalize_fn_t)(const char *orig, char *out, int len);
+
 static canonicalize_fn_t CanonicalizeEntry  = NULL;
 
 // Entry points in zip.dll for loading zip/jar file entries
@@ -980,7 +982,7 @@
     vm_exit_during_initialization("Unable to load java library", NULL);
   }
 
-  CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, dll_lookup(javalib_handle, "Canonicalize", NULL));
+  CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, dll_lookup(javalib_handle, "JDK_Canonicalize", NULL));
 }
 
 void ClassLoader::load_zip_library() {
@@ -1643,13 +1645,12 @@
 bool ClassLoader::get_canonical_path(const char* orig, char* out, int len) {
   assert(orig != NULL && out != NULL && len > 0, "bad arguments");
   JavaThread* THREAD = JavaThread::current();
-  JNIEnv* env = THREAD->jni_environment();
   ResourceMark rm(THREAD);
 
   // os::native_path writes into orig_copy
   char* orig_copy = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(orig)+1);
   strcpy(orig_copy, orig);
-  if ((CanonicalizeEntry)(env, os::native_path(orig_copy), out, len) < 0) {
+  if ((CanonicalizeEntry)(os::native_path(orig_copy), out, len) < 0) {
     return false;
   }
   return true;
--- a/src/hotspot/share/include/jvm.h	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/hotspot/share/include/jvm.h	Fri Dec 06 14:13:10 2019 +0100
@@ -1103,14 +1103,6 @@
                                          JVM_ACC_STRICT | \
                                          JVM_ACC_SYNTHETIC)
 
-/*
- * This is the function defined in libjava.so to perform path
- * canonicalization. VM call this function before opening jar files
- * to load system classes.
- *
- */
-
-typedef int (*canonicalize_fn_t)(JNIEnv *env, char *orig, char *out, int len);
 
 /*************************************************************************
  PART 3: I/O and Network Support
--- a/src/java.base/share/native/libjava/jdk_util.h	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/java.base/share/native/libjava/jdk_util.h	Fri Dec 06 14:13:10 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -45,6 +45,14 @@
 JNIEXPORT void
 JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size);
 
+/*
+ * Export the platform dependent path canonicalization so that
+ * the VM can find it when loading system classes.
+ * This function is also used by the instrumentation agent.
+ */
+JNIEXPORT int
+JDK_Canonicalize(const char *orig, char *out, int len);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
--- a/src/java.base/share/native/libjava/jni_util.c	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/java.base/share/native/libjava/jni_util.c	Fri Dec 06 14:13:10 2019 +0100
@@ -934,20 +934,6 @@
     free((void *)str);
 }
 
-/*
- * Export the platform dependent path canonicalization so that
- * VM can find it when loading system classes.
- * This function is also used by the instrumentation agent.
- */
-extern int canonicalize(char *path, const char *out, int len);
-
-JNIEXPORT int
-Canonicalize(JNIEnv *unused, char *orig, char *out, int len)
-{
-    /* canonicalize an already natived path */
-    return canonicalize(orig, out, len);
-}
-
 JNIEXPORT jclass JNICALL
 JNU_ClassString(JNIEnv *env)
 {
--- a/src/java.base/unix/native/libjava/UnixFileSystem_md.c	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/java.base/unix/native/libjava/UnixFileSystem_md.c	Fri Dec 06 14:13:10 2019 +0100
@@ -45,6 +45,7 @@
 #include "jni.h"
 #include "jni_util.h"
 #include "jlong.h"
+#include "jdk_util.h"
 #include "io_util.h"
 #include "io_util_md.h"
 #include "java_io_FileSystem.h"
@@ -91,8 +92,6 @@
 
 /* -- Path operations -- */
 
-extern int canonicalize(char *path, const char *out, int len);
-
 JNIEXPORT jstring JNICALL
 Java_java_io_UnixFileSystem_canonicalize0(JNIEnv *env, jobject this,
                                           jstring pathname)
@@ -101,7 +100,7 @@
 
     WITH_PLATFORM_STRING(env, pathname, path) {
         char canonicalPath[PATH_MAX];
-        if (canonicalize((char *)path,
+        if (JDK_Canonicalize((char *)path,
                          canonicalPath, PATH_MAX) < 0) {
             JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
         } else {
--- a/src/java.base/unix/native/libjava/canonicalize_md.c	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/java.base/unix/native/libjava/canonicalize_md.c	Fri Dec 06 14:13:10 2019 +0100
@@ -37,6 +37,7 @@
 #include <alloca.h>
 #endif
 
+#include "jdk_util.h"
 
 /* Note: The comments in this file use the terminology
          defined in the java.io.File class */
@@ -186,33 +187,32 @@
    work, though once that's done we still must collapse any remaining "." and
    ".." names by hand. */
 
-int
-canonicalize(char *original, char *resolved, int len)
+JNIEXPORT int
+JDK_Canonicalize(const char *orig, char *out, int len)
 {
     if (len < PATH_MAX) {
         errno = EINVAL;
         return -1;
     }
 
-    if (strlen(original) > PATH_MAX) {
+    if (strlen(orig) > PATH_MAX) {
         errno = ENAMETOOLONG;
         return -1;
     }
 
     /* First try realpath() on the entire path */
-    if (realpath(original, resolved)) {
+    if (realpath(orig, out)) {
         /* That worked, so return it */
-        collapse(resolved);
+        collapse(out);
         return 0;
-    }
-    else {
+    } else {
         /* Something's bogus in the original path, so remove names from the end
            until either some subpath works or we run out of names */
         char *p, *end, *r = NULL;
         char path[PATH_MAX + 1];
 
-        // strlen(original) <= PATH_MAX, see above
-        strncpy(path, original, PATH_MAX);
+        // strlen(orig) <= PATH_MAX, see above
+        strncpy(path, orig, PATH_MAX);
         // append null for == case
         path[PATH_MAX] = '\0';
         end = path + strlen(path);
@@ -225,21 +225,19 @@
 
             /* Try realpath() on this subpath */
             *p = '\0';
-            r = realpath(path, resolved);
+            r = realpath(path, out);
             *p = (p == end) ? '\0' : '/';
 
             if (r != NULL) {
                 /* The subpath has a canonical path */
                 break;
-            }
-            else if (errno == ENOENT || errno == ENOTDIR || errno == EACCES) {
+            } else if (errno == ENOENT || errno == ENOTDIR || errno == EACCES) {
                 /* If the lookup of a particular subpath fails because the file
                    does not exist, because it is of the wrong type, or because
                    access is denied, then remove its last name and try again.
                    Other I/O problems cause an error return. */
                 continue;
-            }
-            else {
+            } else {
                 return -1;
             }
         }
@@ -259,13 +257,11 @@
             strcpy(r + rn, p);
             collapse(r);
             return 0;
-        }
-        else {
+        } else {
             /* Nothing resolved, so just return the original path */
-            strcpy(resolved, path);
-            collapse(resolved);
+            strcpy(out, path);
+            collapse(out);
             return 0;
         }
     }
-
 }
--- a/src/java.base/windows/native/libjava/canonicalize_md.c	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/java.base/windows/native/libjava/canonicalize_md.c	Fri Dec 06 14:13:10 2019 +0100
@@ -37,10 +37,13 @@
 #include <windows.h>
 #include <winbase.h>
 #include <errno.h>
+
+/* We should also include jdk_util.h here, for the prototype of JDK_Canonicalize.
+   This isn't possible though because canonicalize_md.c is as well used in
+   different contexts within Oracle.
+ */
 #include "io_util_md.h"
 
-#undef DEBUG_PATH        /* Define this to debug path code */
-
 /* Copy bytes to dst, not going past dend; return dst + number of bytes copied,
    or NULL if dend would have been exceeded.  If first != '\0', copy that byte
    before copying bytes from src to send - 1. */
@@ -138,10 +141,6 @@
         || (errval == ERROR_NETWORK_ACCESS_DENIED)) {
         return 0;
     }
-
-#ifdef DEBUG_PATH
-    jio_fprintf(stderr, "canonicalize: errval %d\n", errval);
-#endif
     return 1;
 }
 
@@ -326,32 +325,32 @@
 }
 
 /* Non-Wide character version of canonicalize.
-   Converts to whchar and delegates to wcanonicalize. */
-int
-canonicalize(char* orig_path, char* result, int size) {
+   Converts to wchar and delegates to wcanonicalize. */
+JNIEXPORT int
+JDK_Canonicalize(const char *orig, char *out, int len) {
     wchar_t* wpath = NULL;
     wchar_t* wresult = NULL;
     size_t conv;
-    size_t path_len = strlen(orig_path);
+    size_t path_len = strlen(orig);
     int ret = -1;
 
     if ((wpath = (wchar_t*) malloc(sizeof(wchar_t) * (path_len + 1))) == NULL) {
         goto finish;
     }
 
-    if (mbstowcs_s(&conv, wpath, path_len + 1, orig_path, path_len) != 0) {
+    if (mbstowcs_s(&conv, wpath, path_len + 1, orig, path_len) != 0) {
         goto finish;
     }
 
-    if ((wresult = (wchar_t*) malloc(sizeof(wchar_t) * size)) == NULL) {
+    if ((wresult = (wchar_t*) malloc(sizeof(wchar_t) * len)) == NULL) {
         goto finish;
     }
 
-    if (wcanonicalize(wpath, wresult, size) != 0) {
+    if (wcanonicalize(wpath, wresult, len) != 0) {
         goto finish;
     }
 
-    if (wcstombs_s(&conv, result, (size_t) size, wresult, (size_t) (size - 1)) != 0) {
+    if (wcstombs_s(&conv, out, (size_t) len, wresult, (size_t) (len - 1)) != 0) {
         goto finish;
     }
 
@@ -365,15 +364,14 @@
     return ret;
 }
 
-
-/* The appropriate location of getPrefixed() should be io_util_md.c, but
-   java.lang.instrument package has hardwired canonicalize_md.c into their
-   dll, to avoid complicate solution such as including io_util_md.c into
-   that package, as a workaround we put this method here.
+/* The appropriate location of getPrefixed() is io_util_md.c, but it is
+   also used in a non-OpenJDK context within Oracle. There, canonicalize_md.c
+   is already pulled in and compiled, so to avoid more complicated solutions
+   we keep this method here.
  */
 
-/* copy \\?\ or \\?\UNC\ to the front of path*/
-__declspec(dllexport) WCHAR*
+/* copy \\?\ or \\?\UNC\ to the front of path */
+JNIEXPORT WCHAR*
 getPrefixed(const WCHAR* path, int pathlen) {
     WCHAR* pathbuf = (WCHAR*)malloc((pathlen + 10) * sizeof (WCHAR));
     if (pathbuf != 0) {
--- a/src/java.base/windows/native/libjava/io_util_md.h	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/java.base/windows/native/libjava/io_util_md.h	Fri Dec 06 14:13:10 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -38,7 +38,7 @@
  */
 WCHAR* pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE);
 WCHAR* fileToNTPath(JNIEnv *env, jobject file, jfieldID id);
-__declspec(dllexport) WCHAR* getPrefixed(const WCHAR* path, int pathlen);
+JNIEXPORT WCHAR* getPrefixed(const WCHAR* path, int pathlen);
 WCHAR* currentDir(int di);
 int currentDirLength(const WCHAR* path, int pathlen);
 int handleAvailable(FD fd, jlong *pbytes);
--- a/src/java.instrument/share/native/libinstrument/InvocationAdapter.c	Fri Dec 06 13:05:25 2019 +0000
+++ b/src/java.instrument/share/native/libinstrument/InvocationAdapter.c	Fri Dec 06 14:13:10 2019 +0100
@@ -32,6 +32,8 @@
 
 #include    "jni.h"
 
+#include    "jdk_util.h"
+
 #include    "Utilities.h"
 #include    "JPLISAssert.h"
 #include    "JPLISAgent.h"
@@ -776,14 +778,6 @@
     jplis_assert((void*)res != (void*)NULL);     \
 }
 
-/**
- * Convert a pathname to canonical form.
- * This method is exported from libjava.
- */
-extern int
-Canonicalize(JNIEnv *unused, char *orig, char *out, int len);
-
-
 /*
  * This function takes the value of the Boot-Class-Path attribute,
  * splits it into the individual path segments, and then combines it
@@ -904,8 +898,7 @@
             char* resolved;
 
             if (!haveBasePath) {
-                /* Use NULL as the JNIEnv since we know that Canonicalize does not use it. */
-                if (Canonicalize(NULL, (char*)jarfile, canonicalPath, sizeof(canonicalPath)) != 0) {
+                if (JDK_Canonicalize((char*)jarfile, canonicalPath, sizeof(canonicalPath)) != 0) {
                     fprintf(stderr, "WARNING: unable to canonicalize %s\n", jarfile);
                     free(path);
                     continue;