1 /*
2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include <stdlib.h>
27 #include <assert.h>
28
29 #include "jni.h"
30 #include "jni_util.h"
31 #include "jlong.h"
32 #include "jvm.h"
33 #include "check_classname.h"
34 #include "java_lang_ClassLoader.h"
35 #include "java_lang_ClassLoader_NativeLibrary.h"
36 #include <string.h>
37
38 static JNINativeMethod methods[] = {
39 {"retrieveDirectives", "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
40 };
41
42 JNIEXPORT void JNICALL
43 Java_java_lang_ClassLoader_registerNatives(JNIEnv *env, jclass cls)
44 {
45 (*env)->RegisterNatives(env, cls, methods,
46 sizeof(methods)/sizeof(JNINativeMethod));
47 }
48
49 /* Convert java string to UTF char*. Use local buffer if possible,
50 otherwise malloc new memory. Returns null IFF malloc failed. */
51 static char*
52 getUTF(JNIEnv *env, jstring str, char* localBuf, int bufSize)
53 {
54 char* utfStr = NULL;
55
237 cls = JVM_FindClassFromBootLoader(env, clname);
238
239 done:
240 if (clname != buf) {
241 free(clname);
242 }
243
244 return cls;
245 }
246
247 JNIEXPORT jclass JNICALL
248 Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader,
249 jstring name)
250 {
251 if (name == NULL) {
252 return 0;
253 } else {
254 return JVM_FindLoadedClass(env, loader, name);
255 }
256 }
257
258 static jfieldID handleID;
259 static jfieldID jniVersionID;
260 static void *procHandle;
261
262 static jboolean initIDs(JNIEnv *env)
263 {
264 if (handleID == 0) {
265 jclass this =
266 (*env)->FindClass(env, "java/lang/ClassLoader$NativeLibrary");
267 if (this == 0)
268 return JNI_FALSE;
269 handleID = (*env)->GetFieldID(env, this, "handle", "J");
270 if (handleID == 0)
271 return JNI_FALSE;
272 jniVersionID = (*env)->GetFieldID(env, this, "jniVersion", "I");
273 if (jniVersionID == 0)
274 return JNI_FALSE;
275 procHandle = getProcessHandle();
276 }
277 return JNI_TRUE;
278 }
279
280 typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *);
281 typedef void (JNICALL *JNI_OnUnload_t)(JavaVM *, void *);
282
283 /*
284 * Support for finding JNI_On(Un)Load_<lib_name> if it exists.
285 * If cname == NULL then just find normal JNI_On(Un)Load entry point
286 */
287 static void *findJniFunction(JNIEnv *env, void *handle,
288 const char *cname, jboolean isLoad) {
289 const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
290 const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS;
291 const char **syms;
292 int symsLen;
293 void *entryName = NULL;
294 char *jniFunctionName;
295 int i;
296 size_t len;
297
298 // Check for JNI_On(Un)Load<_libname> function
299 if (isLoad) {
300 syms = onLoadSymbols;
301 symsLen = sizeof(onLoadSymbols) / sizeof(char *);
302 } else {
303 syms = onUnloadSymbols;
304 symsLen = sizeof(onUnloadSymbols) / sizeof(char *);
305 }
306 for (i = 0; i < symsLen; i++) {
307 // cname + sym + '_' + '\0'
308 if ((len = (cname != NULL ? strlen(cname) : 0) + strlen(syms[i]) + 2) >
309 FILENAME_MAX) {
310 goto done;
311 }
312 jniFunctionName = malloc(len);
313 if (jniFunctionName == NULL) {
314 JNU_ThrowOutOfMemoryError(env, NULL);
315 goto done;
316 }
317 buildJniFunctionName(syms[i], cname, jniFunctionName);
318 entryName = JVM_FindLibraryEntry(handle, jniFunctionName);
319 free(jniFunctionName);
320 if(entryName) {
321 break;
322 }
323 }
324
325 done:
326 return entryName;
327 }
328
329 /*
330 * Class: java_lang_ClassLoader_NativeLibrary
331 * Method: load0
332 * Signature: (Ljava/lang/String;Z)Z
333 */
334 JNIEXPORT jboolean JNICALL
335 Java_java_lang_ClassLoader_00024NativeLibrary_load0
336 (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin)
337 {
338 const char *cname;
339 jint jniVersion;
340 jthrowable cause;
341 void * handle;
342 jboolean loaded = JNI_FALSE;
343
344 if (!initIDs(env))
345 return JNI_FALSE;
346
347 cname = JNU_GetStringPlatformChars(env, name, 0);
348 if (cname == 0)
349 return JNI_FALSE;
350 handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname);
351 if (handle) {
352 JNI_OnLoad_t JNI_OnLoad;
353 JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle,
354 isBuiltin ? cname : NULL,
355 JNI_TRUE);
356 if (JNI_OnLoad) {
357 JavaVM *jvm;
358 (*env)->GetJavaVM(env, &jvm);
359 jniVersion = (*JNI_OnLoad)(jvm, NULL);
360 } else {
361 jniVersion = 0x00010001;
362 }
363
364 cause = (*env)->ExceptionOccurred(env);
365 if (cause) {
366 (*env)->ExceptionClear(env);
367 (*env)->Throw(env, cause);
368 if (!isBuiltin) {
369 JVM_UnloadLibrary(handle);
370 }
371 goto done;
372 }
373
374 if (!JVM_IsSupportedJNIVersion(jniVersion) ||
375 (isBuiltin && jniVersion < JNI_VERSION_1_8)) {
376 char msg[256];
377 jio_snprintf(msg, sizeof(msg),
378 "unsupported JNI version 0x%08X required by %s",
379 jniVersion, cname);
380 JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg);
381 if (!isBuiltin) {
382 JVM_UnloadLibrary(handle);
383 }
384 goto done;
385 }
386 (*env)->SetIntField(env, this, jniVersionID, jniVersion);
387 } else {
388 cause = (*env)->ExceptionOccurred(env);
389 if (cause) {
390 (*env)->ExceptionClear(env);
391 (*env)->SetLongField(env, this, handleID, (jlong)0);
392 (*env)->Throw(env, cause);
393 }
394 goto done;
395 }
396 (*env)->SetLongField(env, this, handleID, ptr_to_jlong(handle));
397 loaded = JNI_TRUE;
398
399 done:
400 JNU_ReleaseStringPlatformChars(env, name, cname);
401 return loaded;
402 }
403
404 /*
405 * Class: java_lang_ClassLoader_NativeLibrary
406 * Method: unload
407 * Signature: (Ljava/lang/String;ZJ)V
408 */
409 JNIEXPORT void JNICALL
410 Java_java_lang_ClassLoader_00024NativeLibrary_unload
411 (JNIEnv *env, jclass cls, jstring name, jboolean isBuiltin, jlong address)
412 {
413 const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS;
414 void *handle;
415 JNI_OnUnload_t JNI_OnUnload;
416 const char *cname;
417
418 if (!initIDs(env))
419 return;
420 cname = JNU_GetStringPlatformChars(env, name, 0);
421 if (cname == NULL) {
422 return;
423 }
424 handle = jlong_to_ptr(address);
425 JNI_OnUnload = (JNI_OnUnload_t )findJniFunction(env, handle,
426 isBuiltin ? cname : NULL,
427 JNI_FALSE);
428 if (JNI_OnUnload) {
429 JavaVM *jvm;
430 (*env)->GetJavaVM(env, &jvm);
431 (*JNI_OnUnload)(jvm, NULL);
432 }
433 if (!isBuiltin) {
434 JVM_UnloadLibrary(handle);
435 }
436 JNU_ReleaseStringPlatformChars(env, name, cname);
437 }
438
439 /*
440 * Class: java_lang_ClassLoader_NativeLibrary
441 * Method: findEntry
442 * Signature: (Ljava/lang/String;)J
443 */
444 JNIEXPORT jlong JNICALL
445 Java_java_lang_ClassLoader_00024NativeLibrary_findEntry
446 (JNIEnv *env, jobject this, jstring name)
447 {
448 jlong handle;
449 const char *cname;
450 jlong res;
451
452 if (!initIDs(env))
453 return jlong_zero;
454
455 handle = (*env)->GetLongField(env, this, handleID);
456 cname = (*env)->GetStringUTFChars(env, name, 0);
457 if (cname == 0)
458 return jlong_zero;
459 res = ptr_to_jlong(JVM_FindLibraryEntry(jlong_to_ptr(handle), cname));
460 (*env)->ReleaseStringUTFChars(env, name, cname);
461 return res;
462 }
463 /*
464 * Class: java_lang_ClassLoader
465 * Method: findBuiltinLib
466 * Signature: (Ljava/lang/String;)Ljava/lang/String;
467 */
468 JNIEXPORT jstring JNICALL
469 Java_java_lang_ClassLoader_findBuiltinLib
470 (JNIEnv *env, jclass cls, jstring name)
471 {
472 const char *cname;
473 char *libName;
474 size_t prefixLen = strlen(JNI_LIB_PREFIX);
475 size_t suffixLen = strlen(JNI_LIB_SUFFIX);
476 size_t len;
477 jstring lib;
478 void *ret;
479 const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
480
481 if (name == NULL) {
482 JNU_ThrowInternalError(env, "NULL filename for native library");
483 return NULL;
484 }
485 procHandle = getProcessHandle();
486 cname = JNU_GetStringPlatformChars(env, name, 0);
487 if (cname == NULL) {
488 return NULL;
489 }
490 // Copy name Skipping PREFIX
491 len = strlen(cname);
492 if (len <= (prefixLen+suffixLen)) {
493 JNU_ReleaseStringPlatformChars(env, name, cname);
494 return NULL;
495 }
496 libName = malloc(len + 1); //+1 for null if prefix+suffix == 0
497 if (libName == NULL) {
498 JNU_ReleaseStringPlatformChars(env, name, cname);
499 JNU_ThrowOutOfMemoryError(env, NULL);
500 return NULL;
501 }
502 if (len > prefixLen) {
503 strcpy(libName, cname+prefixLen);
504 }
505 JNU_ReleaseStringPlatformChars(env, name, cname);
506
507 // Strip SUFFIX
508 libName[strlen(libName)-suffixLen] = '\0';
509
510 // Check for JNI_OnLoad_libname function
511 ret = findJniFunction(env, procHandle, libName, JNI_TRUE);
512 if (ret != NULL) {
513 lib = JNU_NewStringPlatform(env, libName);
514 free(libName);
515 return lib;
516 }
517 free(libName);
518 return NULL;
519 }
|
1 /*
2 * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include <stdlib.h>
27 #include <assert.h>
28
29 #include "jni.h"
30 #include "jni_util.h"
31 #include "jlong.h"
32 #include "jvm.h"
33 #include "check_classname.h"
34 #include "java_lang_ClassLoader.h"
35 #include <string.h>
36
37 static JNINativeMethod methods[] = {
38 {"retrieveDirectives", "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
39 };
40
41 JNIEXPORT void JNICALL
42 Java_java_lang_ClassLoader_registerNatives(JNIEnv *env, jclass cls)
43 {
44 (*env)->RegisterNatives(env, cls, methods,
45 sizeof(methods)/sizeof(JNINativeMethod));
46 }
47
48 /* Convert java string to UTF char*. Use local buffer if possible,
49 otherwise malloc new memory. Returns null IFF malloc failed. */
50 static char*
51 getUTF(JNIEnv *env, jstring str, char* localBuf, int bufSize)
52 {
53 char* utfStr = NULL;
54
236 cls = JVM_FindClassFromBootLoader(env, clname);
237
238 done:
239 if (clname != buf) {
240 free(clname);
241 }
242
243 return cls;
244 }
245
246 JNIEXPORT jclass JNICALL
247 Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader,
248 jstring name)
249 {
250 if (name == NULL) {
251 return 0;
252 } else {
253 return JVM_FindLoadedClass(env, loader, name);
254 }
255 }
|