1 /* 2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * Adapted from JDK 1.2 linker_md.c v1.37. Note that we #define 28 * NATIVE here, whether or not we're running solaris native threads. 29 * Outside the VM, it's unclear how we can do the locking that is 30 * done in the green threads version of the code below. 31 */ 32 #define NATIVE 33 34 /* 35 * Machine Dependent implementation of the dynamic linking support 36 * for java. This routine is Solaris specific. 37 */ 38 39 #include <stdio.h> 40 #include <dlfcn.h> 41 #include <unistd.h> 42 #include <stdlib.h> 43 #include <string.h> 44 45 #include "path_md.h" 46 #ifndef NATIVE 47 #include "iomgr.h" 48 #include "threads_md.h" 49 #endif 50 51 #ifdef __APPLE__ 52 #define LIB_SUFFIX "dylib" 53 #else 54 #define LIB_SUFFIX "so" 55 #endif 56 57 static void dll_build_name(char* buffer, size_t buflen, 58 const char* pname, const char* fname) { 59 // Based on os_solaris.cpp 60 61 char *path_sep = PATH_SEPARATOR; 62 char *pathname = (char *)pname; 63 while (strlen(pathname) > 0) { 64 char *p = strchr(pathname, *path_sep); 65 if (p == NULL) { 66 p = pathname + strlen(pathname); 67 } 68 /* check for NULL path */ 69 if (p == pathname) { 70 continue; 71 } 72 (void)snprintf(buffer, buflen, "%.*s/lib%s." LIB_SUFFIX, (p - pathname), 73 pathname, fname); 74 75 if (access(buffer, F_OK) == 0) { 76 break; 77 } 78 pathname = p + 1; 79 *buffer = '\0'; 80 } 81 } 82 83 /* 84 * create a string for the JNI native function name by adding the 85 * appropriate decorations. 86 */ 87 int 88 dbgsysBuildFunName(char *name, int nameLen, int args_size, int encodingIndex) 89 { 90 /* On Solaris, there is only one encoding method. */ 91 if (encodingIndex == 0) 92 return 1; 93 return 0; 94 } 95 96 /* 97 * create a string for the dynamic lib open call by adding the 98 * appropriate pre and extensions to a filename and the path 99 */ 100 void 101 dbgsysBuildLibName(char *holder, int holderlen, char *pname, char *fname) 102 { 103 const int pnamelen = pname ? strlen(pname) : 0; 104 105 *holder = '\0'; 106 /* Quietly truncate on buffer overflow. Should be an error. */ 107 if (pnamelen + (int)strlen(fname) + 10 > holderlen) { 108 return; 109 } 110 111 if (pnamelen == 0) { 112 (void)snprintf(holder, holderlen, "lib%s." LIB_SUFFIX, fname); 113 } else { 114 dll_build_name(holder, holderlen, pname, fname); 115 } 116 } 117 118 #ifndef NATIVE 119 extern int thr_main(void); 120 #endif 121 122 void * 123 dbgsysLoadLibrary(const char *name, char *err_buf, int err_buflen) 124 { 125 void * result; 126 #ifdef NATIVE 127 result = dlopen(name, RTLD_LAZY); 128 #else 129 sysMonitorEnter(greenThreadSelf(), &_dl_lock); 130 result = dlopen(name, RTLD_NOW); 131 sysMonitorExit(greenThreadSelf(), &_dl_lock); 132 /* 133 * This is a bit of bulletproofing to catch the commonly occurring 134 * problem of people loading a library which depends on libthread into 135 * the VM. thr_main() should always return -1 which means that libthread 136 * isn't loaded. 137 */ 138 if (thr_main() != -1) { 139 VM_CALL(panic)("libthread loaded into green threads"); 140 } 141 #endif 142 if (result == NULL) { 143 (void)strncpy(err_buf, dlerror(), err_buflen-2); 144 err_buf[err_buflen-1] = '\0'; 145 } 146 return result; 147 } 148 149 void dbgsysUnloadLibrary(void *handle) 150 { 151 #ifndef NATIVE 152 sysMonitorEnter(greenThreadSelf(), &_dl_lock); 153 #endif 154 (void)dlclose(handle); 155 #ifndef NATIVE 156 sysMonitorExit(greenThreadSelf(), &_dl_lock); 157 #endif 158 } 159 160 void * dbgsysFindLibraryEntry(void *handle, const char *name) 161 { 162 void * sym; 163 #ifndef NATIVE 164 sysMonitorEnter(greenThreadSelf(), &_dl_lock); 165 #endif 166 sym = dlsym(handle, name); 167 #ifndef NATIVE 168 sysMonitorExit(greenThreadSelf(), &_dl_lock); 169 #endif 170 return sym; 171 }