LCOV - code coverage report
Current view: top level - native - native.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 163 215 75.8 %
Date: 2017-07-14 10:03:36 Functions: 16 17 94.1 %

          Line data    Source code
       1             : /* src/native/native.cpp - native library support
       2             : 
       3             :    Copyright (C) 1996-2013
       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 "native/jni.hpp"
      38             : #include "native/native.hpp"
      39             : 
      40             : #include "threads/mutex.hpp"
      41             : 
      42             : #include "toolbox/logging.hpp"
      43             : #include "toolbox/buffer.hpp"
      44             : 
      45             : #include "vm/jit/builtin.hpp"
      46             : #include "vm/exceptions.hpp"
      47             : #include "vm/global.hpp"
      48             : #include "vm/globals.hpp"
      49             : #include "vm/hook.hpp"
      50             : #include "vm/loader.hpp"
      51             : #include "vm/options.hpp"
      52             : #include "vm/os.hpp"
      53             : #include "vm/resolve.hpp"
      54             : #include "vm/string.hpp"
      55             : #include "vm/vm.hpp"
      56             : 
      57             : /* native_make_overloaded_function *********************************************
      58             : 
      59             :    XXX
      60             : 
      61             : *******************************************************************************/
      62             : 
      63        5832 : static Utf8String native_make_overloaded_function(Utf8String name, Utf8String descriptor)
      64             : {
      65        5832 :         Buffer<> newname;
      66             :         u2       c;
      67             : 
      68        5832 :         newname.write(name).write("__");
      69             : 
      70        5832 :         Utf8String::utf16_iterator it = descriptor.utf16_begin();
      71             : 
      72       19045 :         for (; (c = *it) != ')'; ++it) {
      73       13213 :                 switch (c) {
      74             :                 case 'Z':
      75             :                 case 'B':
      76             :                 case 'C':
      77             :                 case 'S':
      78             :                 case 'J':
      79             :                 case 'I':
      80             :                 case 'F':
      81             :                 case 'D':
      82        2164 :                         newname.write(c);
      83        2164 :                         break;
      84             :                 case '[':
      85         342 :                         newname.write("_3");
      86         342 :                         break;
      87             :                 case 'L':
      88        4875 :                         newname.write('L');
      89       95532 :                         while ((++it, c = *it) != ';') {
      90      161812 :                                 if (((c >= 'a') && (c <= 'z')) ||
      91             :                                         ((c >= 'A') && (c <= 'Z')) ||
      92             :                                         ((c >= '0') && (c <= '9'))) {
      93       76030 :                                         newname.write(c);
      94             :                                 } else {
      95        9752 :                                         newname.write('_');
      96             :                                 }
      97             :                         }
      98        4875 :                         newname.write("_2");
      99        4875 :                         break;
     100             :                 case '(':
     101        5832 :                         break;
     102             :                 default:
     103           0 :                         assert(0);
     104             :                 }
     105             :         }
     106             : 
     107             :         /* make a utf-string */
     108             : 
     109        5832 :         return newname.utf8_str();
     110             : }
     111             : 
     112             : 
     113             : /* native_insert_char **********************************************************
     114             : 
     115             :    Inserts the passed UTF character into the native method name.  If
     116             :    necessary it is escaped properly.
     117             : 
     118             : *******************************************************************************/
     119             : 
     120      192430 : static inline void native_insert_char(Buffer<>& name, u2 c)
     121             : {
     122             :         char tmp[4];
     123             : 
     124      192430 :         switch (c) {
     125             :         case '/':
     126             :         case '.':
     127             :                 /* replace '/' or '.' with '_' */
     128       13280 :                 name.write('_');
     129       13280 :                 break;
     130             : 
     131             :         case '_':
     132             :                 /* escape sequence for '_' is '_1' */
     133         423 :                 name.write("_1");
     134         423 :                 break;
     135             : 
     136             :         case ';':
     137             :                 /* escape sequence for ';' is '_2' */
     138           0 :                 name.write("_2");
     139           0 :                 break;
     140             : 
     141             :         case '[':
     142             :                 /* escape sequence for '[' is '_3' */
     143           0 :                 name.write("_3");
     144           0 :                 break;
     145             : 
     146             :         default:
     147      178727 :                 if (isalnum(c))
     148      178727 :                         name.write(c);
     149             :                 else {
     150             :                         /* unicode character */
     151           0 :                         name.write("_0");
     152             : 
     153           0 :                         for (s4 i = 0; i < 4; ++i) {
     154           0 :                                 s4 val = (c & 0x0f);
     155           0 :                                 tmp[3 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val);
     156           0 :                                 c >>= 4;
     157             :                         }
     158             : 
     159           0 :                         name.write(tmp, 4);
     160             :                 }
     161             :                 break;
     162             :         }
     163      192430 : }
     164             : 
     165             : /* native_method_symbol ********************************************************
     166             : 
     167             :    Generate a method-symbol string out of the class name and the
     168             :    method name.
     169             : 
     170             : *******************************************************************************/
     171             : 
     172        5832 : static Utf8String native_method_symbol(Utf8String classname, Utf8String methodname)
     173             : {
     174             :         Utf8String::byte_iterator begin, end;
     175             : 
     176             :         /* Calculate length of native function name.  We multiply the
     177             :            class and method name length by 6 as this is the maxium
     178             :            escape-sequence that can be generated (unicode). */
     179             : 
     180             :         /* allocate memory */
     181             : 
     182        5832 :         Buffer<> name;
     183             : 
     184             :         /* generate name of native functions */
     185             : 
     186        5832 :         name.write("Java_");
     187             : 
     188        5832 :         begin = classname.begin();
     189        5832 :         end   = classname.end();
     190             : 
     191      130266 :         for (; begin != end; ++begin) {
     192      124434 :                 native_insert_char(name, *begin);
     193             :         }
     194             : 
     195             :         /* seperator between class and method */
     196             : 
     197        5832 :         name.write('_');
     198             : 
     199        5832 :         begin = methodname.begin();
     200        5832 :         end   = methodname.end();
     201             : 
     202       73828 :         for (; begin != end; ++begin) {
     203       67996 :                 native_insert_char(name, *begin);
     204             :         }
     205             : 
     206             :         /* make a utf-string */
     207             : 
     208        5832 :         return name.utf8_str();
     209             : }
     210             : 
     211             : 
     212      457303 : bool operator< (const NativeMethod& first, const NativeMethod& second)
     213             : {
     214      457303 :         if (first._classname < second._classname)
     215      101929 :                 return true;
     216      355374 :         else if (first._classname > second._classname)
     217      123090 :                 return false;
     218             :                 
     219      232284 :         if (first._name < second._name)
     220       81437 :                 return true;
     221      150847 :         else if (first._name > second._name)
     222      137643 :                 return false;
     223             : 
     224       13204 :         if (first._descriptor < second._descriptor)
     225        3581 :                 return true;
     226        9623 :         else if (first._descriptor > second._descriptor)
     227        1477 :                 return false;
     228             : 
     229             :         // All pointers are equal, we have found the entry.
     230        8146 :         return false;
     231             : }
     232             : 
     233             : 
     234             : /**
     235             :  * Register native methods with the VM.  This is done by inserting
     236             :  * them into the native method table.
     237             :  *
     238             :  * @param classname
     239             :  * @param methods   Native methods array.
     240             :  * @param count     Number of methods in the array.
     241             :  */
     242        3912 : void NativeMethods::register_methods(Utf8String classname, const JNINativeMethod* methods, size_t count)
     243             : {
     244             :         // Insert all methods passed */
     245       43032 :         for (size_t i = 0; i < count; i++) {
     246       39120 :                 if (opt_verbosejni) {
     247           0 :                         printf("[Registering JNI native method ");
     248           0 :                         utf_display_printable_ascii_classname(classname);
     249           0 :                         printf(".%s]\n", methods[i].name);
     250             :                 }
     251             : 
     252             :                 // Generate the UTF8 names.
     253       39120 :                 Utf8String name      = Utf8String::from_utf8(methods[i].name);
     254       39120 :                 Utf8String signature = Utf8String::from_utf8(methods[i].signature);
     255             : 
     256       39120 :                 NativeMethod nm(classname, name, signature, methods[i].fnPtr);
     257             : 
     258             :                 // Insert the method into the table.
     259       39120 :                 _methods.insert(nm);
     260             :         }
     261        3912 : }
     262             : 
     263             : 
     264             : /**
     265             :  * Resolves a native method, maybe from a dynamic library.
     266             :  *
     267             :  * @param m Method structure of the native Java method to resolve.
     268             :  *
     269             :  * @return Pointer to the resolved method (symbol).
     270             :  */
     271        5832 : void* NativeMethods::resolve_method(methodinfo* m)
     272             : {
     273             :         // Verbose output.
     274        5832 :         if (opt_verbosejni) {
     275           0 :                 printf("[Dynamic-linking native method ");
     276           0 :                 utf_display_printable_ascii_classname(m->clazz->name);
     277           0 :                 printf(".");
     278           0 :                 utf_display_printable_ascii(m->name);
     279           0 :                 printf(" ... ");
     280             :         }
     281             : 
     282             :         /* generate method symbol string */
     283             : 
     284        5832 :         Utf8String name = native_method_symbol(m->clazz->name, m->name);
     285             : 
     286             :         /* generate overloaded function (having the types in it's name)           */
     287             : 
     288        5832 :         Utf8String newname = native_make_overloaded_function(name, m->descriptor);
     289             : 
     290             :         // Try to find the symbol.
     291             :         void* symbol;
     292             : 
     293             :         // Try to find the native method symbol in the native methods registered
     294             :         // with the VM.
     295        5832 :         symbol = find_registered_method(m);
     296             : 
     297        5832 :         if (symbol != NULL)
     298        4073 :                 if (opt_verbosejni)
     299           0 :                         printf("internal ");
     300             : 
     301             : #if defined(ENABLE_DL)
     302             :         classloader_t* classloader;
     303        5832 :         if (symbol == NULL) {
     304             :                 // Get the classloader.
     305        1759 :                 classloader = class_get_classloader(m->clazz);
     306             : 
     307             :                 // Resolve the native method name from the native libraries.
     308        1759 :                 NativeLibraries& libraries = VM::get_current()->get_nativelibraries();
     309             : 
     310        1759 :                 symbol = libraries.resolve_symbol(name, classloader);
     311             : 
     312        1759 :                 if (symbol == NULL)
     313         284 :                         symbol = libraries.resolve_symbol(newname, classloader);
     314             :         }
     315             : 
     316             : # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
     317             :         if (symbol == NULL) {
     318             :                 /* We can resolve the function directly from
     319             :                    java.lang.ClassLoader as it's a static function. */
     320             :                 /* XXX should be done in native_init */
     321             : 
     322             :                 methodinfo* method_findNative =
     323             :                         class_resolveclassmethod(class_java_lang_ClassLoader,
     324             :                                                                          utf8::findNative,
     325             :                                                                          utf8::java_lang_ClassLoader_java_lang_String__J,
     326             :                                                                          class_java_lang_ClassLoader,
     327             :                                                                          true);
     328             : 
     329             :                 if (method_findNative != NULL) {
     330             :                         // Try the normal name.
     331             :                         java_handle_t* s = JavaString::from_utf8(name);
     332             :                         symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s);
     333             : 
     334             :                         // If not found, try the mangled name.
     335             :                         if (symbol == NULL) {
     336             :                                 s = JavaString::from_utf8(newname);
     337             :                                 symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s);
     338             :                         }
     339             :                 }
     340             :         }
     341             : # endif
     342             : 
     343        5832 :         if (symbol != NULL)
     344        5831 :                 if (opt_verbosejni)
     345           0 :                         printf("JNI ]\n");
     346             : #endif
     347             : 
     348             :         // Symbol not found?  Throw an exception.
     349        5832 :         if (symbol == NULL) {
     350           1 :                 if (opt_verbosejni)
     351           0 :                         printf("failed ]\n");
     352             : 
     353           1 :                 Buffer<> buf;
     354             : 
     355           1 :                 if (m->clazz)
     356             :                         buf.write(m->clazz->name)
     357           1 :                            .write('.');
     358             : 
     359             :                 buf.write(m->name)
     360           1 :                    .write(m->descriptor);
     361             : 
     362           1 :                 exceptions_throw_unsatisfiedlinkerror(buf.utf8_str());
     363             :         }
     364             : 
     365             :         // Hook point just after method resolving finished.
     366        5832 :         Hook::native_resolved(m, symbol, &symbol);
     367             : 
     368        5832 :         return symbol;
     369             : }
     370             : 
     371             : 
     372             : /**
     373             :  * Try to find the given method in the native methods registered with
     374             :  * the VM.
     375             :  *
     376             :  * @param m Method structure.
     377             :  *
     378             :  * @return Pointer to function if found, NULL otherwise.
     379             :  */
     380        5832 : void* NativeMethods::find_registered_method(methodinfo* m)
     381             : {
     382        5832 :         NativeMethod nm(m);
     383        5832 :         std::set<NativeMethod>::iterator it = _methods.find(nm);
     384             : 
     385        5832 :         if (it == _methods.end())
     386        1759 :                 return NULL;
     387             : 
     388        4073 :         return (*it).get_function();
     389             : }
     390             : 
     391             : 
     392             : /**
     393             :  * Open this native library.
     394             :  *
     395             :  * @return File handle on success, NULL otherwise.
     396             :  */
     397             : #if defined(ENABLE_DL)
     398         432 : void* NativeLibrary::open()
     399             : {
     400         432 :         if (opt_verbosejni) {
     401           0 :                 printf("[Loading native library ");
     402           0 :                 utf_display_printable_ascii(_filename);
     403           0 :                 printf(" ... ");
     404             :         }
     405             : 
     406             :         // Sanity check.
     407         432 :         assert(_filename != NULL);
     408             : 
     409             :         // Try to open the library.
     410         432 :         _handle = os::dlopen(_filename.begin(), RTLD_LAZY);
     411             : 
     412         432 :         if (_handle == NULL) {
     413           4 :                 if (opt_verbosejni)
     414           0 :                         printf("failed ]\n");
     415             : 
     416           4 :                 if (opt_PrintWarnings)
     417           0 :                         log_println("NativeLibrary::open: os::dlopen failed: %s", os::dlerror());
     418             : 
     419           4 :                 return NULL;
     420             :         }
     421             : 
     422         428 :         if (opt_verbosejni)
     423           0 :                 printf("OK ]\n");
     424             : 
     425         428 :         return _handle;
     426             : }
     427             : #endif
     428             : 
     429             : 
     430             : /**
     431             :  * Close this native library.
     432             :  */
     433             : #if defined(ENABLE_DL)
     434           0 : void NativeLibrary::close()
     435             : {
     436           0 :         if (opt_verbosejni) {
     437           0 :                 printf("[Unloading native library ");
     438             : /*              utf_display_printable_ascii(filename); */
     439           0 :                 printf(" ... ");
     440             :         }
     441             : 
     442             :         // Sanity check.
     443           0 :         assert(_handle != NULL);
     444             : 
     445             :         // Close the library.
     446           0 :         int result = os::dlclose(_handle);
     447             : 
     448           0 :         if (result != 0) {
     449           0 :                 if (opt_verbosejni)
     450           0 :                         printf("failed ]\n");
     451             : 
     452           0 :                 if (opt_PrintWarnings)
     453           0 :                         log_println("NativeLibrary::close: os::dlclose failed: %s", os::dlerror());
     454             :         }
     455             : 
     456           0 :         if (opt_verbosejni)
     457           0 :                 printf("OK ]\n");
     458           0 : }
     459             : #endif
     460             : 
     461             : 
     462             : /**
     463             :  * Load this native library and initialize it, if possible.
     464             :  *
     465             :  * @param env JNI environment.
     466             :  *
     467             :  * @return true if library loaded successfully, false otherwise.
     468             :  */
     469         593 : bool NativeLibrary::load(JNIEnv* env)
     470             : {
     471             : #if defined(ENABLE_DL)
     472         593 :         if (_filename == NULL) {
     473           0 :                 exceptions_throw_nullpointerexception();
     474           0 :                 return false;
     475             :         }
     476             : 
     477             :         // Is the library already loaded?
     478         593 :         if (is_loaded())
     479         161 :                 return true;
     480             : 
     481             :         // Open the library.
     482         432 :         open();
     483             : 
     484         432 :         if (_handle == NULL)
     485           4 :                 return false;
     486             : 
     487             : # if defined(ENABLE_JNI)
     488             :         // Resolve JNI_OnLoad function.
     489         428 :         void* onload = os::dlsym(_handle, "JNI_OnLoad");
     490             : 
     491         428 :         if (onload != NULL) {
     492             :                 JNIEXPORT jint (JNICALL *JNI_OnLoad) (JavaVM*, void*);
     493             :                 JavaVM *vm;
     494             : 
     495         423 :                 JNI_OnLoad = (JNIEXPORT jint (JNICALL *)(JavaVM*, void*)) (uintptr_t) onload;
     496             : 
     497         423 :                 env->GetJavaVM(&vm);
     498             : 
     499         423 :                 jint version = JNI_OnLoad(vm, NULL);
     500             : 
     501             :                 // If the version is not 1.2 and not 1.4 the library cannot be
     502             :                 // loaded.
     503         423 :                 if ((version != JNI_VERSION_1_2) && (version != JNI_VERSION_1_4)) {
     504           0 :                         os::dlclose(_handle);
     505           0 :                         return false;
     506             :                 }
     507             :         }
     508             : # endif
     509             : 
     510             :         // Insert the library name into the native library table.
     511         428 :         NativeLibraries& nativelibraries = VM::get_current()->get_nativelibraries();
     512         428 :         nativelibraries.add(*this);
     513             : 
     514         428 :         return true;
     515             : #else
     516             :         os::abort("NativeLibrary::load: Not available in this configuration.");
     517             : 
     518             :         // Keep the compiler happy.
     519             :         return false;
     520             : #endif
     521             : }
     522             : 
     523             : 
     524             : /**
     525             :  * Checks if this native library is loaded.
     526             :  *
     527             :  * @return true if loaded, false otherwise.
     528             :  */
     529             : #if defined(ENABLE_DL)
     530         593 : bool NativeLibrary::is_loaded()
     531             : {
     532         593 :         NativeLibraries& libraries = VM::get_current()->get_nativelibraries();
     533         593 :         return libraries.is_loaded(*this);
     534             : }
     535             : #endif
     536             : 
     537             : 
     538             : /**
     539             :  * Resolve the given symbol in this native library.
     540             :  *
     541             :  * @param symbolname Symbol name.
     542             :  *
     543             :  * @return Pointer to symbol if found, NULL otherwise.
     544             :  */
     545        3323 : void* NativeLibrary::resolve_symbol(Utf8String symbolname) const
     546             : {
     547        3323 :         return os::dlsym(_handle, symbolname.begin());
     548             : }
     549             : 
     550             : 
     551             : /**
     552             :  * Add the given native library to the native libraries table.
     553             :  *
     554             :  * @param library Native library to insert.
     555             :  */
     556             : #if defined(ENABLE_DL)
     557         428 : void NativeLibraries::add(NativeLibrary& library)
     558             : {
     559             :         // Make the container thread-safe.
     560         428 :         _mutex.lock();
     561             : 
     562             :         // XXX Check for double entries.
     563             :         // Insert the native library.
     564         428 :         _libraries.insert(std::make_pair(library.get_classloader(), library));
     565             : 
     566         428 :         _mutex.unlock();
     567         428 : }
     568             : #endif
     569             : 
     570             : 
     571             : /**
     572             :  * Checks if the given native library is loaded.
     573             :  *
     574             :  * @param library Native library.
     575             :  *
     576             :  * @return true if loaded, false otherwise.
     577             :  */
     578         593 : bool NativeLibraries::is_loaded(NativeLibrary& library)
     579             : {
     580         593 :         std::pair<MAP::const_iterator, MAP::const_iterator> its = _libraries.equal_range(library.get_classloader());
     581             : 
     582             :         // No entry for the classloader was found (the range has length
     583             :         // zero).
     584         593 :         if (its.first == its.second)
     585         147 :                 return false;
     586             :         
     587         446 :         MAP::const_iterator it = find_if(its.first, its.second, std::bind2nd(comparator(), library.get_filename()));
     588             : 
     589             :         // No matching entry in the range found.
     590         446 :         if (it == its.second)
     591         285 :                 return false;
     592             : 
     593         161 :         return true;
     594             : }
     595             : 
     596             : 
     597             : /**
     598             :  * Try to find a symbol with the given name in all loaded native
     599             :  * libraries defined by classloader.
     600             :  *
     601             :  * @param symbolname  Name of the symbol to find.
     602             :  * @param classloader Defining classloader.
     603             :  *
     604             :  * @return Pointer to symbol if found, NULL otherwise.
     605             :  */
     606        2043 : void* NativeLibraries::resolve_symbol(Utf8String symbolname, classloader_t* classloader)
     607             : {
     608        2043 :         std::pair<MAP::const_iterator, MAP::const_iterator> its = _libraries.equal_range(classloader);
     609             : 
     610             :         // No entry for the classloader was found (the range has length
     611             :         // zero).
     612        2043 :         if (its.first == its.second)
     613           2 :                 return NULL;
     614             : 
     615        3606 :         for (MAP::const_iterator it = its.first; it != its.second; it++) {
     616        3323 :                 const NativeLibrary& library = (*it).second;
     617        3323 :                 void* symbol = library.resolve_symbol(symbolname);
     618             : 
     619        3323 :                 if (symbol != NULL)
     620        1758 :                         return symbol;
     621             :         }
     622             : 
     623         283 :         return NULL;
     624             : }
     625             : 
     626             : 
     627             : /**
     628             :  * Registers a new native agent by specified by it's library name
     629             :  * and with an optional options string.
     630             :  *
     631             :  * @param library Name of the native agent library.
     632             :  * @param options The options string or NULL if not specified.
     633             :  */
     634             : #if defined(ENABLE_JVMTI)
     635             : void NativeAgents::register_agent_library(char* library, char* options)
     636             : {
     637             :         NativeAgent na(library, options);
     638             : 
     639             :         // Insert native agent into list of agents.
     640             :         _agents.push_back(na);
     641             : }
     642             : #endif
     643             : 
     644             : 
     645             : /**
     646             :  * Registers a new native agent by specified by a path to it's library
     647             :  * and with an optional options string.
     648             :  *
     649             :  * @param path Path of the native agent library.
     650             :  * @param options The options string or NULL if not specified.
     651             :  */
     652             : #if defined(ENABLE_JVMTI)
     653             : void NativeAgents::register_agent_path(char* path, char* options)
     654             : {
     655             :         os::abort("NativeAgents::register_agent_library: Implement me!");
     656             : }
     657             : #endif
     658             : 
     659             : 
     660             : /**
     661             :  * Loads all registered native agents and in turn calls their exported
     662             :  * start-up functions (Agent_OnLoad). If one of the agents reports an
     663             :  * error during start-up, the loading is stopped.
     664             :  *
     665             :  * @return True if all agents were loaded successfully, false if
     666             :  * one of them was not found or reported an error.
     667             :  */
     668             : #if defined(ENABLE_JVMTI)
     669             : bool NativeAgents::load_agents()
     670             : {
     671             :         // Iterate over all registered agents.
     672             :         for (std::vector<NativeAgent>::iterator it = _agents.begin(); it != _agents.end(); ++it) {
     673             :                 NativeAgent& na = *(it);
     674             : 
     675             :                 // Construct agent library name.
     676             :                 Buffer<> buf;
     677             : 
     678             :                 Utf8String u = buf.write(NATIVE_LIBRARY_PREFIX)
     679             :                                   .write(na.get_library())
     680             :                                   .write(NATIVE_LIBRARY_SUFFIX)
     681             :                                   .utf8_str();
     682             : 
     683             :                 // Construct new native library.
     684             :                 NativeLibrary nl(u);
     685             : 
     686             :                 // Try to open the library.
     687             :                 if (nl.open() == NULL)
     688             :                         return false;
     689             : 
     690             :                 // Resolve Agent_OnLoad function.
     691             :                 void* onload = os::dlsym(nl.get_handle(), "Agent_OnLoad");
     692             : 
     693             :                 // Call Agent_OnLoad function if present.
     694             :                 if (onload != NULL) {
     695             :                         JNIEXPORT jint (JNICALL *Agent_OnLoad) (JavaVM*, char*, void*);
     696             :                         JavaVM* vm = VM::get_current()->get_javavm();
     697             : 
     698             :                         Agent_OnLoad = (JNIEXPORT jint (JNICALL *)(JavaVM*, char*, void*)) (uintptr_t) onload;
     699             : 
     700             :                         jint result = Agent_OnLoad(vm, na.get_options(), NULL);
     701             : 
     702             :                         // Check for error in Agent_OnLoad.
     703             :                         if (result != 0) {
     704             :                                 nl.close();
     705             :                                 return false;
     706             :                         }
     707             :                 }
     708             : 
     709             :                 // According to the interface spec, the library _must_ export
     710             :                 // a start-up function.
     711             :                 else {
     712             :                         log_println("NativeAgents::load_agents: Native agent library does not export Agent_OnLoad");
     713             :                         return false;
     714             :                 }
     715             :         }
     716             : 
     717             :         return true;
     718             : }
     719             : #endif
     720             : 
     721             : 
     722             : /* native_new_and_init *********************************************************
     723             : 
     724             :    Creates a new object on the heap and calls the initializer.
     725             :    Returns the object pointer or NULL if memory is exhausted.
     726             :                         
     727             : *******************************************************************************/
     728             : 
     729       42832 : java_handle_t *native_new_and_init(classinfo *c)
     730             : {
     731             :         methodinfo    *m;
     732             :         java_handle_t *o;
     733             : 
     734       42832 :         if (c == NULL)
     735           0 :                 vm_abort("native_new_and_init: c == NULL");
     736             : 
     737             :         /* create object */
     738             : 
     739       42832 :         o = builtin_new(c);
     740             :         
     741       42832 :         if (o == NULL)
     742           0 :                 return NULL;
     743             : 
     744             :         /* try to find the initializer */
     745             : 
     746       42832 :         m = class_findmethod(c, utf8::init, utf8::void__void);
     747             :                                                       
     748             :         /* ATTENTION: returning the object here is ok, since the class may
     749             :        not have an initializer */
     750             : 
     751       42832 :         if (m == NULL)
     752           0 :                 return o;
     753             : 
     754             :         /* call initializer */
     755             : 
     756       42832 :         (void) vm_call_method(m, o);
     757             : 
     758       42832 :         return o;
     759             : }
     760             : 
     761             : 
     762         873 : java_handle_t *native_new_and_init_string(classinfo *c, java_handle_t *s)
     763             : {
     764             :         methodinfo    *m;
     765             :         java_handle_t *o;
     766             : 
     767         873 :         if (c == NULL)
     768           0 :                 vm_abort("native_new_and_init_string: c == NULL");
     769             : 
     770             :         /* create object */
     771             : 
     772         873 :         o = builtin_new(c);
     773             : 
     774         873 :         if (o == NULL)
     775           0 :                 return NULL;
     776             : 
     777             :         /* find initializer */
     778             : 
     779         873 :         m = class_findmethod(c, utf8::init, utf8::java_lang_String__void);
     780             : 
     781             :         /* initializer not found */
     782             : 
     783         873 :         if (m == NULL)
     784           0 :                 return NULL;
     785             : 
     786             :         /* call initializer */
     787             : 
     788         873 :         (void) vm_call_method(m, o, s);
     789             : 
     790         873 :         return o;
     791             : }
     792             : 
     793             : 
     794             : /*
     795             :  * These are local overrides for various environment variables in Emacs.
     796             :  * Please do not remove this and leave it at the end of the file, where
     797             :  * Emacs will automagically detect them.
     798             :  * ---------------------------------------------------------------------
     799             :  * Local variables:
     800             :  * mode: c++
     801             :  * indent-tabs-mode: t
     802             :  * c-basic-offset: 4
     803             :  * tab-width: 4
     804             :  * End:
     805             :  * vim:noexpandtab:sw=4:ts=4:
     806             :  */

Generated by: LCOV version 1.11