Home | History | Annotate | Download | only in back
      1 /*
      2  * Copyright (c) 1998, 2013, 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* paths, const char* fname) {
     59     char *path, *paths_copy, *next_token;
     60 
     61     paths_copy = strdup(paths);
     62     if (paths_copy == NULL) {
     63         return;
     64     }
     65 
     66     next_token = NULL;
     67     path = strtok_r(paths_copy, PATH_SEPARATOR, &next_token);
     68 
     69     while (path != NULL) {
     70         snprintf(buffer, buflen, "%s/lib%s." LIB_SUFFIX, path, fname);
     71         if (access(buffer, F_OK) == 0) {
     72             break;
     73         }
     74         *buffer = '\0';
     75         path = strtok_r(NULL, PATH_SEPARATOR, &next_token);
     76     }
     77 
     78     free(paths_copy);
     79 }
     80 
     81 /*
     82  * create a string for the JNI native function name by adding the
     83  * appropriate decorations.
     84  */
     85 int
     86 dbgsysBuildFunName(char *name, int nameLen, int args_size, int encodingIndex)
     87 {
     88   /* On Solaris, there is only one encoding method. */
     89     if (encodingIndex == 0)
     90         return 1;
     91     return 0;
     92 }
     93 
     94 /*
     95  * create a string for the dynamic lib open call by adding the
     96  * appropriate pre and extensions to a filename and the path
     97  */
     98 void
     99 dbgsysBuildLibName(char *holder, int holderlen, const char *pname, const char *fname)
    100 {
    101     const int pnamelen = pname ? strlen(pname) : 0;
    102 
    103     *holder = '\0';
    104     /* Quietly truncate on buffer overflow.  Should be an error. */
    105     if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
    106         return;
    107     }
    108 
    109     if (pnamelen == 0) {
    110         (void)snprintf(holder, holderlen, "lib%s." LIB_SUFFIX, fname);
    111     } else {
    112       dll_build_name(holder, holderlen, pname, fname);
    113     }
    114 }
    115 
    116 #ifndef NATIVE
    117 extern int thr_main(void);
    118 #endif
    119 
    120 void *
    121 dbgsysLoadLibrary(const char *name, char *err_buf, int err_buflen)
    122 {
    123     void * result;
    124 #ifdef NATIVE
    125     result = dlopen(name, RTLD_LAZY);
    126 #else
    127     sysMonitorEnter(greenThreadSelf(), &_dl_lock);
    128     result = dlopen(name, RTLD_NOW);
    129     sysMonitorExit(greenThreadSelf(), &_dl_lock);
    130     /*
    131      * This is a bit of bulletproofing to catch the commonly occurring
    132      * problem of people loading a library which depends on libthread into
    133      * the VM.  thr_main() should always return -1 which means that libthread
    134      * isn't loaded.
    135      */
    136     if (thr_main() != -1) {
    137          VM_CALL(panic)("libthread loaded into green threads");
    138     }
    139 #endif
    140     if (result == NULL) {
    141         (void)strncpy(err_buf, dlerror(), err_buflen-2);
    142         err_buf[err_buflen-1] = '\0';
    143     }
    144     return result;
    145 }
    146 
    147 void dbgsysUnloadLibrary(void *handle)
    148 {
    149 #ifndef NATIVE
    150     sysMonitorEnter(greenThreadSelf(), &_dl_lock);
    151 #endif
    152     (void)dlclose(handle);
    153 #ifndef NATIVE
    154     sysMonitorExit(greenThreadSelf(), &_dl_lock);
    155 #endif
    156 }
    157 
    158 void * dbgsysFindLibraryEntry(void *handle, const char *name)
    159 {
    160     void * sym;
    161 #ifndef NATIVE
    162     sysMonitorEnter(greenThreadSelf(), &_dl_lock);
    163 #endif
    164     sym =  dlsym(handle, name);
    165 #ifndef NATIVE
    166     sysMonitorExit(greenThreadSelf(), &_dl_lock);
    167 #endif
    168     return sym;
    169 }
    170