Home | History | Annotate | Download | only in utils
      1 /* Copyright (C) 2011 The Android Open Source Project
      2 **
      3 ** This software is licensed under the terms of the GNU General Public
      4 ** License version 2, as published by the Free Software Foundation, and
      5 ** may be copied, distributed, and modified under those terms.
      6 **
      7 ** This program is distributed in the hope that it will be useful,
      8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 ** GNU General Public License for more details.
     11 */
     12 #include <android/utils/dll.h>
     13 #include <android/utils/system.h>
     14 #include <android/utils/path.h>
     15 
     16 #include <stdlib.h>
     17 
     18 /* Utility function, append one string to another, caller must free result */
     19 static char*
     20 append_string( const char* str1, const char* str2 )
     21 {
     22     int   len1   = strlen(str1);
     23     int   len2   = strlen(str2);
     24     char* result = malloc(len1+len2+1);
     25 
     26     if (result != NULL) {
     27         memcpy(result, str1, len1);
     28         memcpy(result + len1, str2, len2);
     29         result[len1+len2] = '\0';
     30     }
     31     return result;
     32 }
     33 
     34 #ifdef _WIN32
     35 
     36 #include <windows.h>
     37 
     38 /* This function is used to revert all forward slashes (/) in a path
     39  * string into unquoted backwards one (\). This is necessary because
     40  * LoadLibrary() and AddDllDirectory() do not support forward slashes.
     41  *
     42  * Caller must free the result string
     43  */
     44 static char*
     45 reverse_slashes( const char* path )
     46 {
     47     int   len    = strlen(path);
     48     char* result = malloc(len+1);
     49     int   nn;
     50 
     51     for (nn = 0; nn < len; nn++) {
     52         int ch = path[nn];
     53         if (ch == '/') {
     54             ch = '\\';
     55         }
     56         result[nn] = (char)ch;
     57     }
     58     result[nn] = '\0';
     59 
     60     return result;
     61 }
     62 
     63 ADynamicLibrary*
     64 adynamicLibrary_open( const char*  libraryName,
     65                       char**       pError)
     66 {
     67     char*  libName = (char*) libraryName;
     68     void*  result;
     69 
     70     /* Append a .dll to the library name if it doesn't have an extension */
     71     if (strchr(libraryName,'.') == NULL) {
     72         libName = append_string(libraryName, ".dll");
     73     }
     74 
     75     /* Now do our magic */
     76     *pError = NULL;
     77     result = (ADynamicLibrary*) LoadLibrary( libName );
     78     if (result == NULL) {
     79         *pError = ASTRDUP("Could not load DLL!");
     80     }
     81 
     82     /* Free the library name if we modified it */
     83     if (libName != libraryName) {
     84         free(libName);
     85     }
     86 
     87     return (ADynamicLibrary*) result;
     88 }
     89 
     90 void*
     91 adynamicLibrary_findSymbol( ADynamicLibrary*  lib,
     92                             const char*       symbolName,
     93                             char**            pError)
     94 {
     95     void* result;
     96 
     97     *pError = NULL;
     98 
     99     if (lib == NULL) {
    100         *pError = strdup("NULL library pointer");
    101         return NULL;
    102     }
    103     if (symbolName == NULL || symbolName[0] == '\0') {
    104         *pError = strdup("NULL or empty symbolName");
    105         return NULL;
    106     }
    107     result = GetProcAddress( (HMODULE)lib, symbolName );
    108     if (result == NULL) {
    109         *pError = ASTRDUP("Could not find symbol");
    110     }
    111     return result;
    112 }
    113 
    114 /* Close/unload a given dynamic library */
    115 void
    116 adynamicLibrary_close( ADynamicLibrary*  lib )
    117 {
    118     if (lib != NULL) {
    119         FreeLibrary( (HMODULE)lib );
    120     }
    121 }
    122 
    123 #else /* !_WIN32 */
    124 
    125 #include <dlfcn.h>
    126 #include <stdlib.h>
    127 
    128 ADynamicLibrary*
    129 adynamicLibrary_open( const char*  libraryName,
    130                       char**       pError)
    131 {
    132     char*  libName = (char*) libraryName;
    133     void*  result;
    134 
    135 #ifdef __APPLE__
    136 #  define SO_EXTENSION ".dylib"
    137 #else
    138 #  define SO_EXTENSION ".so"
    139 #endif
    140 
    141     /* Append a .so to the library name if it doesn't have an extension */
    142     if (strchr(libraryName,'.') == NULL) {
    143         libName = append_string(libraryName, SO_EXTENSION);
    144     }
    145 
    146     /* Now do our magic */
    147     *pError = NULL;
    148     result  = dlopen( libName, RTLD_LAZY );
    149     if (result == NULL) {
    150         *pError = strdup(dlerror());
    151     }
    152 
    153     /* Free the library name if we modified it */
    154     if (libName != (char*)libraryName) {
    155         free(libName);
    156     }
    157 
    158     return (ADynamicLibrary*) result;
    159 }
    160 
    161 void*
    162 adynamicLibrary_findSymbol( ADynamicLibrary*  lib,
    163                             const char*       symbolName,
    164                             char**            pError)
    165 {
    166     void* result;
    167 
    168     *pError = NULL;
    169 
    170     if (lib == NULL) {
    171         *pError = strdup("NULL library pointer");
    172         return NULL;
    173     }
    174     if (symbolName == NULL || symbolName[0] == '\0') {
    175         *pError = strdup("NULL or empty symbolName");
    176         return NULL;
    177     }
    178     result = dlsym(lib, symbolName);
    179     if (result == NULL) {
    180         *pError = strdup(dlerror());
    181     }
    182     return result;
    183 }
    184 
    185 /* Close/unload a given dynamic library */
    186 void
    187 adynamicLibrary_close( ADynamicLibrary*  lib )
    188 {
    189     if (lib != NULL) {
    190         dlclose(lib);
    191     }
    192 }
    193 
    194 #endif /* !_WIN32 */
    195