* src/toolbox/sequence.hpp: Added new file to hold sequence builder class.
[cacao.git] / src / native / native.cpp
1 /* src/native/native.cpp - native library support
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <ctype.h>
30
31 #include <stdint.h>
32
33 #include <algorithm>
34 #include <functional>
35 #include <map>
36
37 #include "mm/memory.hpp"
38
39 #include "native/jni.hpp"
40 #include "native/native.hpp"
41
42 #include "threads/mutex.hpp"
43
44 #include "toolbox/logging.hpp"
45
46 #include "vm/jit/builtin.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/global.h"
49 #include "vm/globals.hpp"
50 #include "vm/loader.hpp"
51 #include "vm/options.h"
52 #include "vm/os.hpp"
53 #include "vm/resolve.hpp"
54 #include "vm/string.hpp"
55 #include "vm/vm.hpp"
56
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/jit.hpp"
59
60
61 /* native_make_overloaded_function *********************************************
62
63    XXX
64
65 *******************************************************************************/
66
67 static utf *native_make_overloaded_function(utf *name, utf *descriptor)
68 {
69         char *newname;
70         s4    namelen;
71         char *utf_ptr;
72         u2    c;
73         s4    i;
74         utf  *u;
75
76         utf_ptr = descriptor->text;
77         namelen = strlen(name->text) + strlen("__") + strlen("0");
78
79         /* calculate additional length */
80
81         while ((c = utf_nextu2(&utf_ptr)) != ')') {
82                 switch (c) {
83                 case 'Z':
84                 case 'B':
85                 case 'C':
86                 case 'S':
87                 case 'I':
88                 case 'J':
89                 case 'F':
90                 case 'D':
91                         namelen++;
92                         break;
93                 case '[':
94                         namelen += 2;
95                         break;
96                 case 'L':
97                         namelen++;
98                         while (utf_nextu2(&utf_ptr) != ';')
99                                 namelen++;
100                         namelen += 2;
101                         break;
102                 case '(':
103                         break;
104                 default:
105                         assert(0);
106                 }
107         }
108
109         /* reallocate memory */
110
111         i = strlen(name->text);
112
113         newname = MNEW(char, namelen);
114         MCOPY(newname, name->text, char, i);
115
116         utf_ptr = descriptor->text;
117
118         newname[i++] = '_';
119         newname[i++] = '_';
120
121         while ((c = utf_nextu2(&utf_ptr)) != ')') {
122                 switch (c) {
123                 case 'Z':
124                 case 'B':
125                 case 'C':
126                 case 'S':
127                 case 'J':
128                 case 'I':
129                 case 'F':
130                 case 'D':
131                         newname[i++] = c;
132                         break;
133                 case '[':
134                         newname[i++] = '_';
135                         newname[i++] = '3';
136                         break;
137                 case 'L':
138                         newname[i++] = 'L';
139                         while ((c = utf_nextu2(&utf_ptr)) != ';')
140                                 if (((c >= 'a') && (c <= 'z')) ||
141                                         ((c >= 'A') && (c <= 'Z')) ||
142                                         ((c >= '0') && (c <= '9')))
143                                         newname[i++] = c;
144                                 else
145                                         newname[i++] = '_';
146                         newname[i++] = '_';
147                         newname[i++] = '2';
148                         break;
149                 case '(':
150                         break;
151                 default:
152                         assert(0);
153                 }
154         }
155
156         /* close string */
157
158         newname[i] = '\0';
159
160         /* make a utf-string */
161
162         u = utf_new_char(newname);
163
164         /* release memory */
165
166         MFREE(newname, char, namelen);
167
168         return u;
169 }
170
171
172 /* native_insert_char **********************************************************
173
174    Inserts the passed UTF character into the native method name.  If
175    necessary it is escaped properly.
176
177 *******************************************************************************/
178
179 static s4 native_insert_char(char *name, u4 pos, u2 c)
180 {
181         s4 val;
182         s4 i;
183
184         switch (c) {
185         case '/':
186         case '.':
187                 /* replace '/' or '.' with '_' */
188                 name[pos] = '_';
189                 break;
190
191         case '_':
192                 /* escape sequence for '_' is '_1' */
193                 name[pos]   = '_';
194                 name[++pos] = '1';
195                 break;
196
197         case ';':
198                 /* escape sequence for ';' is '_2' */
199                 name[pos]   = '_';
200                 name[++pos] = '2';
201                 break;
202
203         case '[':
204                 /* escape sequence for '[' is '_1' */
205                 name[pos]   = '_';
206                 name[++pos] = '3';
207                 break;
208
209         default:
210                 if (isalnum(c))
211                         name[pos] = c;
212                 else {
213                         /* unicode character */
214                         name[pos]   = '_';
215                         name[++pos] = '0';
216
217                         for (i = 0; i < 4; ++i) {
218                                 val = c & 0x0f;
219                                 name[pos + 4 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val);
220                                 c >>= 4;
221                         }
222
223                         pos += 4;
224                 }
225                 break;
226         }
227
228         /* return the new buffer index */
229
230         return pos;
231 }
232
233
234 /* native_method_symbol ********************************************************
235
236    Generate a method-symbol string out of the class name and the
237    method name.
238
239 *******************************************************************************/
240
241 static utf *native_method_symbol(utf *classname, utf *methodname)
242 {
243         char *name;
244         s4    namelen;
245         char *utf_ptr;
246         char *utf_endptr;
247         u2    c;
248         u4    pos;
249         utf  *u;
250
251         /* Calculate length of native function name.  We multiply the
252            class and method name length by 6 as this is the maxium
253            escape-sequence that can be generated (unicode). */
254
255         namelen =
256                 strlen("Java_") +
257                 utf_get_number_of_u2s(classname) * 6 +
258                 strlen("_") +
259                 utf_get_number_of_u2s(methodname) * 6 +
260                 strlen("0");
261
262         /* allocate memory */
263
264         name = MNEW(char, namelen);
265
266         /* generate name of native functions */
267
268         strcpy(name, "Java_");
269         pos = strlen("Java_");
270
271         utf_ptr    = classname->text;
272         utf_endptr = UTF_END(classname);
273
274         for (; utf_ptr < utf_endptr; utf_ptr++, pos++) {
275                 c   = *utf_ptr;
276                 pos = native_insert_char(name, pos, c);
277         }
278
279         /* seperator between class and method */
280
281         name[pos++] = '_';
282
283         utf_ptr    = methodname->text;
284         utf_endptr = UTF_END(methodname);
285
286         for (; utf_ptr < utf_endptr; utf_ptr++, pos++) {
287                 c   = *utf_ptr;
288                 pos = native_insert_char(name, pos, c);
289         }
290
291         /* close string */
292
293         name[pos] = '\0';
294
295         /* check for an buffer overflow */
296
297         assert((int32_t) pos <= namelen);
298
299         /* make a utf-string */
300
301         u = utf_new_char(name);
302
303         /* release memory */
304
305         MFREE(name, char, namelen);
306
307         return u;
308 }
309
310
311 bool operator< (const NativeMethod& first, const NativeMethod& second)
312 {
313         if (first._classname < second._classname)
314                 return true;
315         else if (first._classname > second._classname)
316                 return false;
317                 
318         if (first._name < second._name)
319                 return true;
320         else if (first._name > second._name)
321                 return false;
322
323         if (first._descriptor < second._descriptor)
324                 return true;
325         else if (first._descriptor > second._descriptor)
326                 return false;
327
328         // All pointers are equal, we have found the entry.
329         return false;
330 }
331
332
333 /**
334  * Register native methods with the VM.  This is done by inserting
335  * them into the native method table.
336  *
337  * @param classname
338  * @param methods   Native methods array.
339  * @param count     Number of methods in the array.
340  */
341 void NativeMethods::register_methods(utf* classname, const JNINativeMethod* methods, size_t count)
342 {
343         // Insert all methods passed */
344         for (size_t i = 0; i < count; i++) {
345                 if (opt_verbosejni) {
346                         printf("[Registering JNI native method ");
347                         utf_display_printable_ascii_classname(classname);
348                         printf(".%s]\n", methods[i].name);
349                 }
350
351                 // Generate the UTF8 names.
352                 utf* name      = utf_new_char(methods[i].name);
353                 utf* signature = utf_new_char(methods[i].signature);
354
355                 NativeMethod nm(classname, name, signature, methods[i].fnPtr);
356
357                 // Insert the method into the table.
358                 _methods.insert(nm);
359         }
360 }
361
362
363 /**
364  * Resolves a native method, maybe from a dynamic library.
365  *
366  * @param m Method structure of the native Java method to resolve.
367  *
368  * @return Pointer to the resolved method (symbol).
369  */
370 void* NativeMethods::resolve_method(methodinfo* m)
371 {
372         // Verbose output.
373         if (opt_verbosejni) {
374                 printf("[Dynamic-linking native method ");
375                 utf_display_printable_ascii_classname(m->clazz->name);
376                 printf(".");
377                 utf_display_printable_ascii(m->name);
378                 printf(" ... ");
379         }
380
381         /* generate method symbol string */
382
383         utf* name = native_method_symbol(m->clazz->name, m->name);
384
385         /* generate overloaded function (having the types in it's name)           */
386
387         utf* newname = native_make_overloaded_function(name, m->descriptor);
388
389         // Try to find the symbol.
390         void* symbol;
391
392         // Try to find the native method symbol in the native methods registered
393         // with the VM.
394         symbol = find_registered_method(m);
395
396         if (symbol != NULL)
397                 if (opt_verbosejni)
398                         printf("internal ]\n");
399
400 #if defined(ENABLE_DL)
401         classloader_t* classloader;
402         if (symbol == NULL) {
403                 // Get the classloader.
404                 classloader = class_get_classloader(m->clazz);
405
406                 // Resolve the native method name from the native libraries.
407                 NativeLibraries& libraries = VM::get_current()->get_nativelibraries();
408
409                 symbol = libraries.resolve_symbol(name, classloader);
410
411                 if (symbol == NULL)
412                         symbol = libraries.resolve_symbol(newname, classloader);
413         }
414
415 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
416         if (symbol == NULL) {
417                 /* We can resolve the function directly from
418                    java.lang.ClassLoader as it's a static function. */
419                 /* XXX should be done in native_init */
420
421                 methodinfo* method_findNative =
422                         class_resolveclassmethod(class_java_lang_ClassLoader,
423                                                                          utf_findNative,
424                                                                          utf_java_lang_ClassLoader_java_lang_String__J,
425                                                                          class_java_lang_ClassLoader,
426                                                                          true);
427
428                 if (method_findNative != NULL) {
429                         // Try the normal name.
430                         java_handle_t* s = javastring_new(name);
431                         symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s);
432
433                         // If not found, try the mangled name.
434                         if (symbol == NULL) {
435                                 s = javastring_new(newname);
436                                 symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s);
437                         }
438                 }
439         }
440 # endif
441
442         if (symbol != NULL)
443                 if (opt_verbosejni)
444                         printf("JNI ]\n");
445 #endif
446
447         // Symbol not found?  Throw an exception.
448         if (symbol == NULL) {
449                 if (opt_verbosejni)
450                         printf("failed ]\n");
451
452                 exceptions_throw_unsatisfiedlinkerror(m->name);
453         }
454
455         return symbol;
456 }
457
458
459 /**
460  * Try to find the given method in the native methods registered with
461  * the VM.
462  *
463  * @param m Method structure.
464  *
465  * @return Pointer to function if found, NULL otherwise.
466  */
467 void* NativeMethods::find_registered_method(methodinfo* m)
468 {
469         NativeMethod nm(m);
470         std::set<NativeMethod>::iterator it = _methods.find(nm);
471
472         if (it == _methods.end())
473                 return NULL;
474
475         return (*it).get_function();
476 }
477
478
479 /**
480  * Open this native library.
481  *
482  * @return File handle on success, NULL otherwise.
483  */
484 #if defined(ENABLE_DL)
485 void* NativeLibrary::open()
486 {
487         if (opt_verbosejni) {
488                 printf("[Loading native library ");
489                 utf_display_printable_ascii(_filename);
490                 printf(" ... ");
491         }
492
493         // Sanity check.
494         assert(_filename != NULL);
495
496         // Try to open the library.
497         _handle = os::dlopen(_filename->text, RTLD_LAZY);
498
499         if (_handle == NULL) {
500                 if (opt_verbosejni)
501                         printf("failed ]\n");
502
503                 if (opt_verbose) {
504                         log_start();
505                         log_print("NativeLibrary::open: os::dlopen failed: ");
506                         log_print(os::dlerror());
507                         log_finish();
508                 }
509
510                 return NULL;
511         }
512
513         if (opt_verbosejni)
514                 printf("OK ]\n");
515
516         return _handle;
517 }
518 #endif
519
520
521 /**
522  * Close this native library.
523  */
524 #if defined(ENABLE_DL)
525 void NativeLibrary::close()
526 {
527         if (opt_verbosejni) {
528                 printf("[Unloading native library ");
529 /*              utf_display_printable_ascii(filename); */
530                 printf(" ... ");
531         }
532
533         // Sanity check.
534         assert(_handle != NULL);
535
536         // Close the library.
537         int result = os::dlclose(_handle);
538
539         if (result != 0) {
540                 if (opt_verbosejni)
541                         printf("failed ]\n");
542
543                 if (opt_verbose) {
544                         log_start();
545                         log_print("NativeLibrary::close: os::dlclose failed: ");
546                         log_print(os::dlerror());
547                         log_finish();
548                 }
549         }
550
551         if (opt_verbosejni)
552                 printf("OK ]\n");
553 }
554 #endif
555
556
557 /**
558  * Load this native library and initialize it, if possible.
559  *
560  * @param env JNI environment.
561  *
562  * @return true if library loaded successfully, false otherwise.
563  */
564 bool NativeLibrary::load(JNIEnv* env)
565 {
566 #if defined(ENABLE_DL)
567         if (_filename == NULL) {
568                 exceptions_throw_nullpointerexception();
569                 return false;
570         }
571
572         // Is the library already loaded?
573         if (is_loaded())
574                 return true;
575
576         // Open the library.
577         open();
578
579         if (_handle == NULL)
580                 return false;
581
582 # if defined(ENABLE_JNI)
583         // Resolve JNI_OnLoad function.
584         void* onload = os::dlsym(_handle, "JNI_OnLoad");
585
586         if (onload != NULL) {
587                 JNIEXPORT jint (JNICALL *JNI_OnLoad) (JavaVM*, void*);
588                 JavaVM *vm;
589
590                 JNI_OnLoad = (JNIEXPORT jint (JNICALL *)(JavaVM*, void*)) (uintptr_t) onload;
591
592                 env->GetJavaVM(&vm);
593
594                 jint version = JNI_OnLoad(vm, NULL);
595
596                 // If the version is not 1.2 and not 1.4 the library cannot be
597                 // loaded.
598                 if ((version != JNI_VERSION_1_2) && (version != JNI_VERSION_1_4)) {
599                         os::dlclose(_handle);
600                         return false;
601                 }
602         }
603 # endif
604
605         // Insert the library name into the native library table.
606         NativeLibraries& nativelibraries = VM::get_current()->get_nativelibraries();
607         nativelibraries.add(*this);
608
609         return true;
610 #else
611         os::abort("NativeLibrary::load: Not available in this configuration.");
612
613         // Keep the compiler happy.
614         return false;
615 #endif
616 }
617
618
619 /**
620  * Checks if this native library is loaded.
621  *
622  * @return true if loaded, false otherwise.
623  */
624 #if defined(ENABLE_DL)
625 bool NativeLibrary::is_loaded()
626 {
627         NativeLibraries& libraries = VM::get_current()->get_nativelibraries();
628         return libraries.is_loaded(*this);
629 }
630 #endif
631
632
633 /**
634  * Resolve the given symbol in this native library.
635  *
636  * @param symbolname Symbol name.
637  *
638  * @return Pointer to symbol if found, NULL otherwise.
639  */
640 void* NativeLibrary::resolve_symbol(utf* symbolname) const
641 {
642         return os::dlsym(_handle, symbolname->text);
643 }
644
645
646 /**
647  * Add the given native library to the native libraries table.
648  *
649  * @param library Native library to insert.
650  */
651 #if defined(ENABLE_DL)
652 void NativeLibraries::add(NativeLibrary& library)
653 {
654         // Make the container thread-safe.
655         _mutex.lock();
656
657         // XXX Check for double entries.
658         // Insert the native library.
659         _libraries.insert(std::make_pair(library.get_classloader(), library));
660
661         _mutex.unlock();
662 }
663 #endif
664
665
666 /**
667  * Checks if the given native library is loaded.
668  *
669  * @param library Native library.
670  *
671  * @return true if loaded, false otherwise.
672  */
673 bool NativeLibraries::is_loaded(NativeLibrary& library)
674 {
675         std::pair<MAP::const_iterator, MAP::const_iterator> its = _libraries.equal_range(library.get_classloader());
676
677         // No entry for the classloader was found (the range has length
678         // zero).
679         if (its.first == its.second)
680                 return false;
681         
682         MAP::const_iterator it = find_if(its.first, its.second, std::bind2nd(comparator(), library.get_filename()));
683
684         // No matching entry in the range found.
685         if (it == its.second)
686                 return false;
687
688         return true;
689 }
690
691
692 /**
693  * Try to find a symbol with the given name in all loaded native
694  * libraries defined by classloader.
695  *
696  * @param symbolname  Name of the symbol to find.
697  * @param classloader Defining classloader.
698  *
699  * @return Pointer to symbol if found, NULL otherwise.
700  */
701 void* NativeLibraries::resolve_symbol(utf* symbolname, classloader_t* classloader)
702 {
703         std::pair<MAP::const_iterator, MAP::const_iterator> its = _libraries.equal_range(classloader);
704
705         // No entry for the classloader was found (the range has length
706         // zero).
707         if (its.first == its.second)
708                 return NULL;
709
710         for (MAP::const_iterator it = its.first; it != its.second; it++) {
711                 const NativeLibrary& library = (*it).second;
712                 void* symbol = library.resolve_symbol(symbolname);
713
714                 if (symbol != NULL)
715                         return symbol;
716         }
717
718         return NULL;
719 }
720
721
722 /**
723  * Registers a new native agent by specified by it's library name
724  * and with an optional options string.
725  *
726  * @param library Name of the native agent library.
727  * @param options The options string or NULL if not specified.
728  */
729 #if defined(ENABLE_JVMTI)
730 void NativeAgents::register_agent_library(char* library, char* options)
731 {
732         NativeAgent na(library, options);
733
734         // Insert native agent into list of agents.
735         _agents.push_back(na);
736 }
737 #endif
738
739
740 /**
741  * Registers a new native agent by specified by a path to it's library
742  * and with an optional options string.
743  *
744  * @param path Path of the native agent library.
745  * @param options The options string or NULL if not specified.
746  */
747 #if defined(ENABLE_JVMTI)
748 void NativeAgents::register_agent_path(char* path, char* options)
749 {
750         os::abort("NativeAgents::register_agent_library: Implement me!");
751 }
752 #endif
753
754
755 /**
756  * Loads all registered native agents and in turn calls their exported
757  * start-up functions (Agent_OnLoad). If one of the agents reports an
758  * error during start-up, the loading is stopped.
759  *
760  * @return True if all agents were loaded successfully, false if
761  * one of them was not found or reported an error.
762  */
763 #if defined(ENABLE_JVMTI)
764 bool NativeAgents::load_agents()
765 {
766         // Iterate over all registered agents.
767         for (std::vector<NativeAgent>::iterator it = _agents.begin(); it != _agents.end(); ++it) {
768                 NativeAgent& na = *(it);
769
770                 // Construct agent library name.
771                 size_t len =
772                         os::strlen(NATIVE_LIBRARY_PREFIX) +
773                         os::strlen(na.get_library()) +
774                         os::strlen(NATIVE_LIBRARY_SUFFIX) +
775                         os::strlen("0");
776
777                 char* p = MNEW(char, len);
778
779                 os::strcpy(p, NATIVE_LIBRARY_PREFIX);
780                 os::strcat(p, na.get_library());
781                 os::strcat(p, NATIVE_LIBRARY_SUFFIX);
782
783                 utf* u = utf_new_char(p);
784
785                 MFREE(p, char, len);
786
787                 // Construct new native library.
788                 NativeLibrary nl(u);
789
790                 // Try to open the library.
791                 if (nl.open() == NULL)
792                         return false;
793
794                 // Resolve Agent_OnLoad function.
795                 void* onload = os::dlsym(nl.get_handle(), "Agent_OnLoad");
796
797                 // Call Agent_OnLoad function if present.
798                 if (onload != NULL) {
799                         JNIEXPORT jint (JNICALL *Agent_OnLoad) (JavaVM*, char*, void*);
800                         JavaVM* vm = VM::get_current()->get_javavm();
801
802                         Agent_OnLoad = (JNIEXPORT jint (JNICALL *)(JavaVM*, char*, void*)) (uintptr_t) onload;
803
804                         jint result = Agent_OnLoad(vm, na.get_options(), NULL);
805
806                         // Check for error in Agent_OnLoad.
807                         if (result != 0) {
808                                 nl.close();
809                                 return false;
810                         }
811                 }
812
813                 // According to the interface spec, the library _must_ export
814                 // a start-up function.
815                 else {
816                         log_println("NativeAgents::load_agents: Native agent library does not export Agent_OnLoad");
817                         return false;
818                 }
819         }
820
821         return true;
822 }
823 #endif
824
825
826 /* native_new_and_init *********************************************************
827
828    Creates a new object on the heap and calls the initializer.
829    Returns the object pointer or NULL if memory is exhausted.
830                         
831 *******************************************************************************/
832
833 java_handle_t *native_new_and_init(classinfo *c)
834 {
835         methodinfo    *m;
836         java_handle_t *o;
837
838         if (c == NULL)
839                 vm_abort("native_new_and_init: c == NULL");
840
841         /* create object */
842
843         o = builtin_new(c);
844         
845         if (o == NULL)
846                 return NULL;
847
848         /* try to find the initializer */
849
850         m = class_findmethod(c, utf_init, utf_void__void);
851                                                       
852         /* ATTENTION: returning the object here is ok, since the class may
853        not have an initializer */
854
855         if (m == NULL)
856                 return o;
857
858         /* call initializer */
859
860         (void) vm_call_method(m, o);
861
862         return o;
863 }
864
865
866 java_handle_t *native_new_and_init_string(classinfo *c, java_handle_t *s)
867 {
868         methodinfo    *m;
869         java_handle_t *o;
870
871         if (c == NULL)
872                 vm_abort("native_new_and_init_string: c == NULL");
873
874         /* create object */
875
876         o = builtin_new(c);
877
878         if (o == NULL)
879                 return NULL;
880
881         /* find initializer */
882
883         m = class_findmethod(c, utf_init, utf_java_lang_String__void);
884
885         /* initializer not found */
886
887         if (m == NULL)
888                 return NULL;
889
890         /* call initializer */
891
892         (void) vm_call_method(m, o, s);
893
894         return o;
895 }
896
897
898 /*
899  * These are local overrides for various environment variables in Emacs.
900  * Please do not remove this and leave it at the end of the file, where
901  * Emacs will automagically detect them.
902  * ---------------------------------------------------------------------
903  * Local variables:
904  * mode: c++
905  * indent-tabs-mode: t
906  * c-basic-offset: 4
907  * tab-width: 4
908  * End:
909  * vim:noexpandtab:sw=4:ts=4:
910  */