1 /*
2  * Copyright (c) 1997, 2017, 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.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "memory/oopFactory.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "memory/universe.inline.hpp"
32 #include "oops/instanceKlass.hpp"
33 #include "oops/method.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "oops/symbol.hpp"
36 #include "prims/jvm_misc.hpp"
37 #include "prims/nativeLookup.hpp"
38 #include "runtime/arguments.hpp"
39 #include "runtime/handles.inline.hpp"
40 #include "runtime/javaCalls.hpp"
41 #include "runtime/sharedRuntime.hpp"
42 #include "runtime/signature.hpp"
43 #include "utilities/macros.hpp"
44 #if INCLUDE_JFR
45 #include "jfr/jfr.hpp"
46 #endif
47 #ifdef TARGET_OS_FAMILY_linux
48 # include "os_linux.inline.hpp"
49 #endif
50 #ifdef TARGET_OS_FAMILY_solaris
51 # include "os_solaris.inline.hpp"
52 #endif
53 #ifdef TARGET_OS_FAMILY_windows
54 # include "os_windows.inline.hpp"
55 #endif
56 #ifdef TARGET_OS_FAMILY_aix
57 # include "os_aix.inline.hpp"
58 #endif
59 #ifdef TARGET_OS_FAMILY_bsd
60 # include "os_bsd.inline.hpp"
61 #endif
62 
63 
64 /*
65 
66 The JNI specification defines the mapping from a Java native method name to
67 a C native library implementation function name as follows:
68 
69   The mapping produces a native method name by concatenating the following components
70   derived from a `native` method declaration:
71 
72   1. the prefix Java_
73   2. given the binary name, in internal form, of the class which declares the native method:
74      the result of escaping the name.
75   3. an underscore ("_")
76   4. the escaped method name
77   5. if the native method declaration is overloaded: two underscores ("__") followed by the
78    escaped parameter descriptor (JVMS 4.3.3) of the method declaration.
79 
80   Escaping leaves every alphanumeric ASCII character (A-Za-z0-9) unchanged, and replaces each
81   UTF-16 code unit n the table below with the corresponding escape sequence. If the name to be
82   escaped contains a surrogate pair, then the high-surrogate code unit and the low-surrogate code
83   unit are escaped separately. The result of escaping is a string consisting only of the ASCII
84   characters A-Za-z0-9 and underscore.
85 
86   ------------------------------                  ------------------------------------
87   UTF-16 code unit                                Escape sequence
88   ------------------------------                  ------------------------------------
89   Forward slash (/, U+002F)                       _
90   Underscore (_, U+005F)                          _1
91   Semicolon (;, U+003B)                           _2
92   Left square bracket ([, U+005B)                 _3
93   Any UTF-16 code unit \u_WXYZ_ that does not     _0wxyz where w, x, y, and z are the lower-case
94   represent alphanumeric ASCII (A-Za-z0-9),       forms of the hexadecimal digits W, X, Y, and Z.
95   forward slash, underscore, semicolon,           (For example, U+ABCD becomes _0abcd.)
96   or left square bracket
97   ------------------------------                  ------------------------------------
98 
99   Note that escape sequences can safely begin _0, _1, etc, because class and method
100   names in Java source code never begin with a number. However, that is not the case in
101   class files that were not generated from Java source code.
102 
103   To preserve the 1:1 mapping to a native method name, the VM checks the resulting name as
104   follows. If the process of escaping any precursor string from the native  method declaration
105   (class or method name, or argument type) causes a "0", "1", "2", or "3" character
106   from the precursor string to appear unchanged in the result *either* immediately after an
107   underscore *or* at the beginning of the escaped string (where it will follow an underscore
108   in the fully assembled name), then the escaping process is said to have "failed".
109   In such cases, no native library search is performed, and the attempt to link the native
110   method invocation will throw UnsatisfiedLinkError.
111 
112 
113 For example:
114 
115   package/my_class/method
116 
117 and
118 
119   package/my/1class/method
120 
121 both map to
122 
123   Java_package_my_1class_method
124 
125 To address this potential conflict we need only check if the character after
126 / is a digit 0..3, or if the first character after an injected '_' seperator
127 is a digit 0..3. If we encounter an invalid identifier we reset the
128 stringStream and return false. Otherwise the stringStream contains the mapped
129 name and we return true.
130 
131 To address legacy compatibility, the UseLegacyJNINameEscaping flag can be set
132 which skips the extra checks.
133 
134 */
map_escaped_name_on(stringStream * st,Symbol * name,int begin,int end)135 static bool map_escaped_name_on(stringStream* st, Symbol* name, int begin, int end) {
136   char* bytes = (char*)name->bytes() + begin;
137   char* end_bytes = (char*)name->bytes() + end;
138   bool check_escape_char = true; // initially true as first character here follows '_'
139   while (bytes < end_bytes) {
140     jchar c;
141     bytes = UTF8::next(bytes, &c);
142     if (c <= 0x7f && isalnum(c)) {
143       if (check_escape_char && (c >= '0' && c <= '3') &&
144           !UseLegacyJNINameEscaping) {
145         // This is a non-Java identifier and we won't escape it to
146         // ensure no name collisions with a Java identifier.
147         if (PrintJNIResolving) {
148           ResourceMark rm;
149           tty->print_cr("[Lookup of native method with non-Java identifier rejected: %s]",
150                                   name->as_C_string());
151         }
152         st->reset();  // restore to "" on error
153         return false;
154       }
155       st->put((char) c);
156       check_escape_char = false;
157     } else {
158       check_escape_char = false;
159       if (c == '_') st->print("_1");
160       else if (c == '/') {
161         st->print("_");
162         // Following a / we must have non-escape character
163         check_escape_char = true;
164       }
165       else if (c == ';') st->print("_2");
166       else if (c == '[') st->print("_3");
167       else               st->print("_%.5x", c);
168     }
169   }
170   return true;
171 }
172 
173 
map_escaped_name_on(stringStream * st,Symbol * name)174 static bool map_escaped_name_on(stringStream* st, Symbol* name) {
175   return map_escaped_name_on(st, name, 0, name->utf8_length());
176 }
177 
178 
pure_jni_name(methodHandle method)179 char* NativeLookup::pure_jni_name(methodHandle method) {
180   stringStream st;
181   // Prefix
182   st.print("Java_");
183   // Klass name
184   if (!map_escaped_name_on(&st, method->klass_name())) {
185     return NULL;
186   }
187   st.print("_");
188   // Method name
189   if (!map_escaped_name_on(&st, method->name())) {
190     return NULL;
191   }
192   return st.as_string();
193 }
194 
195 
critical_jni_name(methodHandle method)196 char* NativeLookup::critical_jni_name(methodHandle method) {
197   stringStream st;
198   // Prefix
199   st.print("JavaCritical_");
200   // Klass name
201   if (!map_escaped_name_on(&st, method->klass_name())) {
202     return NULL;
203   }
204   st.print("_");
205   // Method name
206   if (!map_escaped_name_on(&st, method->name())) {
207     return NULL;
208   }
209   return st.as_string();
210 }
211 
212 
long_jni_name(methodHandle method)213 char* NativeLookup::long_jni_name(methodHandle method) {
214   // Signatures ignore the wrapping parentheses and the trailing return type
215   stringStream st;
216   Symbol* signature = method->signature();
217   st.print("__");
218   // find ')'
219   int end;
220   for (end = 0; end < signature->utf8_length() && signature->byte_at(end) != ')'; end++);
221   // skip first '('
222   if (!map_escaped_name_on(&st, signature, 1, end)) {
223     return NULL;
224   }
225 
226   return st.as_string();
227 }
228 
229 extern "C" {
230   void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls);
231   void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
232   void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
233   void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass);
234 }
235 
236 #define CC (char*)  /* cast a literal from (const char*) */
237 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
238 
239 static JNINativeMethod lookup_special_native_methods[] = {
240   { CC"Java_sun_misc_Unsafe_registerNatives",                      NULL, FN_PTR(JVM_RegisterUnsafeMethods)       },
241   { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
242   { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         },
243   { CC"Java_sun_hotspot_WhiteBox_registerNatives",                 NULL, FN_PTR(JVM_RegisterWhiteBoxMethods)     },
244 #if INCLUDE_JFR
245   { CC"Java_jdk_jfr_internal_JVM_registerNatives",                 NULL, FN_PTR(jfr_register_natives)            },
246 #endif
247 };
248 
lookup_special_native(char * jni_name)249 static address lookup_special_native(char* jni_name) {
250   int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod);
251   for (int i = 0; i < count; i++) {
252     // NB: To ignore the jni prefix and jni postfix strstr is used matching.
253     if (strstr(jni_name, lookup_special_native_methods[i].name) != NULL) {
254       return CAST_FROM_FN_PTR(address, lookup_special_native_methods[i].fnPtr);
255     }
256   }
257   return NULL;
258 }
259 
lookup_style(methodHandle method,char * pure_name,const char * long_name,int args_size,bool os_style,bool & in_base_library,TRAPS)260 address NativeLookup::lookup_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
261   address entry;
262   // Compute complete JNI name for style
263   stringStream st;
264   if (os_style) os::print_jni_name_prefix_on(&st, args_size);
265   st.print_raw(pure_name);
266   st.print_raw(long_name);
267   if (os_style) os::print_jni_name_suffix_on(&st, args_size);
268   char* jni_name = st.as_string();
269 
270   // If the loader is null we have a system class, so we attempt a lookup in
271   // the native Java library. This takes care of any bootstrapping problems.
272   // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find
273   // gets found the first time around - otherwise an infinite loop can occure. This is
274   // another VM/library dependency
275   Handle loader(THREAD, method->method_holder()->class_loader());
276   if (loader.is_null()) {
277     entry = lookup_special_native(jni_name);
278     if (entry == NULL) {
279        entry = (address) os::dll_lookup(os::native_java_library(), jni_name);
280     }
281     if (entry != NULL) {
282       in_base_library = true;
283       return entry;
284     }
285   }
286 
287   // Otherwise call static method findNative in ClassLoader
288   KlassHandle   klass (THREAD, SystemDictionary::ClassLoader_klass());
289   Handle name_arg = java_lang_String::create_from_str(jni_name, CHECK_NULL);
290 
291   JavaValue result(T_LONG);
292   JavaCalls::call_static(&result,
293                          klass,
294                          vmSymbols::findNative_name(),
295                          vmSymbols::classloader_string_long_signature(),
296                          // Arguments
297                          loader,
298                          name_arg,
299                          CHECK_NULL);
300   entry = (address) (intptr_t) result.get_jlong();
301 
302   if (entry == NULL) {
303     // findNative didn't find it, if there are any agent libraries look in them
304     AgentLibrary* agent;
305     for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
306       entry = (address) os::dll_lookup(agent->os_lib(), jni_name);
307       if (entry != NULL) {
308         return entry;
309       }
310     }
311   }
312 
313   return entry;
314 }
315 
316 
lookup_critical_style(methodHandle method,char * pure_name,const char * long_name,int args_size,bool os_style)317 address NativeLookup::lookup_critical_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style) {
318   if (!method->has_native_function()) {
319     return NULL;
320   }
321 
322   address current_entry = method->native_function();
323 
324   char dll_name[JVM_MAXPATHLEN];
325   int offset;
326   if (os::dll_address_to_library_name(current_entry, dll_name, sizeof(dll_name), &offset)) {
327     char ebuf[32];
328     void* dll = os::dll_load(dll_name, ebuf, sizeof(ebuf));
329     if (dll != NULL) {
330       // Compute complete JNI name for style
331       stringStream st;
332       if (os_style) os::print_jni_name_prefix_on(&st, args_size);
333       st.print_raw(pure_name);
334       st.print_raw(long_name);
335       if (os_style) os::print_jni_name_suffix_on(&st, args_size);
336       char* jni_name = st.as_string();
337       return (address)os::dll_lookup(dll, jni_name);
338     }
339   }
340 
341   return NULL;
342 }
343 
344 
345 // Check all the formats of native implementation name to see if there is one
346 // for the specified method.
lookup_entry(methodHandle method,bool & in_base_library,TRAPS)347 address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) {
348   address entry = NULL;
349   in_base_library = false;
350   // Compute pure name
351   char* pure_name = pure_jni_name(method);
352   if (pure_name == NULL) {
353     // JNI name mapping rejected this method so return
354     // NULL to indicate UnsatisfiedLinkError should be thrown.
355     return NULL;
356   }
357 
358   // Compute argument size
359   int args_size = 1                             // JNIEnv
360                 + (method->is_static() ? 1 : 0) // class for static methods
361                 + method->size_of_parameters(); // actual parameters
362 
363 
364   // 1) Try JNI short style
365   entry = lookup_style(method, pure_name, "",        args_size, true,  in_base_library, CHECK_NULL);
366   if (entry != NULL) return entry;
367 
368   // Compute long name
369   char* long_name = long_jni_name(method);
370   if (long_name == NULL) {
371     // JNI name mapping rejected this method so return
372     // NULL to indicate UnsatisfiedLinkError should be thrown.
373     return NULL;
374   }
375 
376   // 2) Try JNI long style
377   entry = lookup_style(method, pure_name, long_name, args_size, true,  in_base_library, CHECK_NULL);
378   if (entry != NULL) return entry;
379 
380   // 3) Try JNI short style without os prefix/suffix
381   entry = lookup_style(method, pure_name, "",        args_size, false, in_base_library, CHECK_NULL);
382   if (entry != NULL) return entry;
383 
384   // 4) Try JNI long style without os prefix/suffix
385   entry = lookup_style(method, pure_name, long_name, args_size, false, in_base_library, CHECK_NULL);
386 
387   return entry; // NULL indicates not found
388 }
389 
390 // Check all the formats of native implementation name to see if there is one
391 // for the specified method.
lookup_critical_entry(methodHandle method)392 address NativeLookup::lookup_critical_entry(methodHandle method) {
393   if (!CriticalJNINatives) return NULL;
394 
395   if (method->is_synchronized() ||
396       !method->is_static()) {
397     // Only static non-synchronized methods are allowed
398     return NULL;
399   }
400 
401   ResourceMark rm;
402   address entry = NULL;
403 
404   Symbol* signature = method->signature();
405   for (int end = 0; end < signature->utf8_length(); end++) {
406     if (signature->byte_at(end) == 'L') {
407       // Don't allow object types
408       return NULL;
409     }
410   }
411 
412   // Compute critical name
413   char* critical_name = critical_jni_name(method);
414   if (critical_name == NULL) {
415     // JNI name mapping rejected this method so return
416     // NULL to indicate UnsatisfiedLinkError should be thrown.
417     return NULL;
418   }
419 
420   // Compute argument size
421   int args_size = 1                             // JNIEnv
422                 + (method->is_static() ? 1 : 0) // class for static methods
423                 + method->size_of_parameters(); // actual parameters
424 
425 
426   // 1) Try JNI short style
427   entry = lookup_critical_style(method, critical_name, "",        args_size, true);
428   if (entry != NULL) return entry;
429 
430   // Compute long name
431   char* long_name = long_jni_name(method);
432   if (long_name == NULL) {
433     // JNI name mapping rejected this method so return
434     // NULL to indicate UnsatisfiedLinkError should be thrown.
435     return NULL;
436   }
437 
438   // 2) Try JNI long style
439   entry = lookup_critical_style(method, critical_name, long_name, args_size, true);
440   if (entry != NULL) return entry;
441 
442   // 3) Try JNI short style without os prefix/suffix
443   entry = lookup_critical_style(method, critical_name, "",        args_size, false);
444   if (entry != NULL) return entry;
445 
446   // 4) Try JNI long style without os prefix/suffix
447   entry = lookup_critical_style(method, critical_name, long_name, args_size, false);
448 
449   return entry; // NULL indicates not found
450 }
451 
452 // Check if there are any JVM TI prefixes which have been applied to the native method name.
453 // If any are found, remove them before attemping the look up of the
454 // native implementation again.
455 // See SetNativeMethodPrefix in the JVM TI Spec for more details.
lookup_entry_prefixed(methodHandle method,bool & in_base_library,TRAPS)456 address NativeLookup::lookup_entry_prefixed(methodHandle method, bool& in_base_library, TRAPS) {
457 #if INCLUDE_JVMTI
458   ResourceMark rm(THREAD);
459 
460   int prefix_count;
461   char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
462   char* in_name = method->name()->as_C_string();
463   char* wrapper_name = in_name;
464   // last applied prefix will be first -- go backwards
465   for (int i = prefix_count-1; i >= 0; i--) {
466     char* prefix = prefixes[i];
467     size_t prefix_len = strlen(prefix);
468     if (strncmp(prefix, wrapper_name, prefix_len) == 0) {
469       // has this prefix remove it
470       wrapper_name += prefix_len;
471     }
472   }
473   if (wrapper_name != in_name) {
474     // we have a name for a wrapping method
475     int wrapper_name_len = (int)strlen(wrapper_name);
476     TempNewSymbol wrapper_symbol = SymbolTable::probe(wrapper_name, wrapper_name_len);
477     if (wrapper_symbol != NULL) {
478       KlassHandle kh(method->method_holder());
479       Method* wrapper_method = kh()->lookup_method(wrapper_symbol,
480                                                                   method->signature());
481       if (wrapper_method != NULL && !wrapper_method->is_native()) {
482         // we found a wrapper method, use its native entry
483         method->set_is_prefixed_native();
484         return lookup_entry(wrapper_method, in_base_library, THREAD);
485       }
486     }
487   }
488 #endif // INCLUDE_JVMTI
489   return NULL;
490 }
491 
lookup_base(methodHandle method,bool & in_base_library,TRAPS)492 address NativeLookup::lookup_base(methodHandle method, bool& in_base_library, TRAPS) {
493   address entry = NULL;
494   ResourceMark rm(THREAD);
495 
496   entry = lookup_entry(method, in_base_library, THREAD);
497   if (entry != NULL) return entry;
498 
499   // standard native method resolution has failed.  Check if there are any
500   // JVM TI prefixes which have been applied to the native method name.
501   entry = lookup_entry_prefixed(method, in_base_library, THREAD);
502   if (entry != NULL) return entry;
503 
504   // Native function not found, throw UnsatisfiedLinkError
505   THROW_MSG_0(vmSymbols::java_lang_UnsatisfiedLinkError(),
506               method->name_and_sig_as_C_string());
507 }
508 
509 
lookup(methodHandle method,bool & in_base_library,TRAPS)510 address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
511   if (!method->has_native_function()) {
512     address entry = lookup_base(method, in_base_library, CHECK_NULL);
513     method->set_native_function(entry,
514       Method::native_bind_event_is_interesting);
515     // -verbose:jni printing
516     if (PrintJNIResolving) {
517       ResourceMark rm(THREAD);
518       tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
519         method->method_holder()->external_name(),
520         method->name()->as_C_string());
521     }
522   }
523   return method->native_function();
524 }
525 
base_library_lookup(const char * class_name,const char * method_name,const char * signature)526 address NativeLookup::base_library_lookup(const char* class_name, const char* method_name, const char* signature) {
527   EXCEPTION_MARK;
528   bool in_base_library = true;  // SharedRuntime inits some math methods.
529   TempNewSymbol c_name = SymbolTable::new_symbol(class_name,  CATCH);
530   TempNewSymbol m_name = SymbolTable::new_symbol(method_name, CATCH);
531   TempNewSymbol s_name = SymbolTable::new_symbol(signature,   CATCH);
532 
533   // Find the class
534   Klass* k = SystemDictionary::resolve_or_fail(c_name, true, CATCH);
535   instanceKlassHandle klass (THREAD, k);
536 
537   // Find method and invoke standard lookup
538   methodHandle method (THREAD,
539                        klass->uncached_lookup_method(m_name, s_name, Klass::find_overpass));
540   address result = lookup(method, in_base_library, CATCH);
541   assert(in_base_library, "must be in basic library");
542   guarantee(result != NULL, "must be non NULL");
543   return result;
544 }
545