1 /* |
1 /* |
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
89 mangle_name_on(&st, method->name()); |
89 mangle_name_on(&st, method->name()); |
90 return st.as_string(); |
90 return st.as_string(); |
91 } |
91 } |
92 |
92 |
93 |
93 |
|
94 char* NativeLookup::critical_jni_name(methodHandle method) { |
|
95 stringStream st; |
|
96 // Prefix |
|
97 st.print("JavaCritical_"); |
|
98 // Klass name |
|
99 mangle_name_on(&st, method->klass_name()); |
|
100 st.print("_"); |
|
101 // Method name |
|
102 mangle_name_on(&st, method->name()); |
|
103 return st.as_string(); |
|
104 } |
|
105 |
|
106 |
94 char* NativeLookup::long_jni_name(methodHandle method) { |
107 char* NativeLookup::long_jni_name(methodHandle method) { |
95 // Signature ignore the wrapping parenteses and the trailing return type |
108 // Signature ignore the wrapping parenteses and the trailing return type |
96 stringStream st; |
109 stringStream st; |
97 Symbol* signature = method->signature(); |
110 Symbol* signature = method->signature(); |
98 st.print("__"); |
111 st.print("__"); |
191 |
204 |
192 return entry; |
205 return entry; |
193 } |
206 } |
194 |
207 |
195 |
208 |
|
209 address NativeLookup::lookup_critical_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style) { |
|
210 if (!method->has_native_function()) { |
|
211 return NULL; |
|
212 } |
|
213 |
|
214 address current_entry = method->native_function(); |
|
215 |
|
216 char dll_name[JVM_MAXPATHLEN]; |
|
217 int offset; |
|
218 if (os::dll_address_to_library_name(current_entry, dll_name, sizeof(dll_name), &offset)) { |
|
219 char ebuf[32]; |
|
220 void* dll = os::dll_load(dll_name, ebuf, sizeof(ebuf)); |
|
221 if (dll != NULL) { |
|
222 // Compute complete JNI name for style |
|
223 stringStream st; |
|
224 if (os_style) os::print_jni_name_prefix_on(&st, args_size); |
|
225 st.print_raw(pure_name); |
|
226 st.print_raw(long_name); |
|
227 if (os_style) os::print_jni_name_suffix_on(&st, args_size); |
|
228 char* jni_name = st.as_string(); |
|
229 return (address)os::dll_lookup(dll, jni_name); |
|
230 } |
|
231 } |
|
232 |
|
233 return NULL; |
|
234 } |
|
235 |
|
236 |
196 // Check all the formats of native implementation name to see if there is one |
237 // Check all the formats of native implementation name to see if there is one |
197 // for the specified method. |
238 // for the specified method. |
198 address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) { |
239 address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) { |
199 address entry = NULL; |
240 address entry = NULL; |
200 in_base_library = false; |
241 in_base_library = false; |
222 entry = lookup_style(method, pure_name, "", args_size, false, in_base_library, CHECK_NULL); |
263 entry = lookup_style(method, pure_name, "", args_size, false, in_base_library, CHECK_NULL); |
223 if (entry != NULL) return entry; |
264 if (entry != NULL) return entry; |
224 |
265 |
225 // 4) Try JNI long style without os prefix/suffix |
266 // 4) Try JNI long style without os prefix/suffix |
226 entry = lookup_style(method, pure_name, long_name, args_size, false, in_base_library, CHECK_NULL); |
267 entry = lookup_style(method, pure_name, long_name, args_size, false, in_base_library, CHECK_NULL); |
|
268 |
|
269 return entry; // NULL indicates not found |
|
270 } |
|
271 |
|
272 // Check all the formats of native implementation name to see if there is one |
|
273 // for the specified method. |
|
274 address NativeLookup::lookup_critical_entry(methodHandle method) { |
|
275 if (!CriticalJNINatives) return NULL; |
|
276 |
|
277 if (method->is_synchronized() || |
|
278 !method->is_static()) { |
|
279 // Only static non-synchronized methods are allowed |
|
280 return NULL; |
|
281 } |
|
282 |
|
283 ResourceMark rm; |
|
284 address entry = NULL; |
|
285 |
|
286 Symbol* signature = method->signature(); |
|
287 for (int end = 0; end < signature->utf8_length(); end++) { |
|
288 if (signature->byte_at(end) == 'L') { |
|
289 // Don't allow object types |
|
290 return NULL; |
|
291 } |
|
292 } |
|
293 |
|
294 // Compute critical name |
|
295 char* critical_name = critical_jni_name(method); |
|
296 |
|
297 // Compute argument size |
|
298 int args_size = 1 // JNIEnv |
|
299 + (method->is_static() ? 1 : 0) // class for static methods |
|
300 + method->size_of_parameters(); // actual parameters |
|
301 |
|
302 |
|
303 // 1) Try JNI short style |
|
304 entry = lookup_critical_style(method, critical_name, "", args_size, true); |
|
305 if (entry != NULL) return entry; |
|
306 |
|
307 // Compute long name |
|
308 char* long_name = long_jni_name(method); |
|
309 |
|
310 // 2) Try JNI long style |
|
311 entry = lookup_critical_style(method, critical_name, long_name, args_size, true); |
|
312 if (entry != NULL) return entry; |
|
313 |
|
314 // 3) Try JNI short style without os prefix/suffix |
|
315 entry = lookup_critical_style(method, critical_name, "", args_size, false); |
|
316 if (entry != NULL) return entry; |
|
317 |
|
318 // 4) Try JNI long style without os prefix/suffix |
|
319 entry = lookup_critical_style(method, critical_name, long_name, args_size, false); |
227 |
320 |
228 return entry; // NULL indicates not found |
321 return entry; // NULL indicates not found |
229 } |
322 } |
230 |
323 |
231 // Check if there are any JVM TI prefixes which have been applied to the native method name. |
324 // Check if there are any JVM TI prefixes which have been applied to the native method name. |