dso_dlfcn.c: make it work on Tru64 4.0.
[openssl.git] / crypto / dso / dso_dlfcn.c
index 979fca80654f850d7bad358fd9fe426971111cc7..5f2254806ca903d71d3f261d042db1345fcfbe4f 100644 (file)
@@ -64,7 +64,6 @@
 # ifndef _GNU_SOURCE
 #  define _GNU_SOURCE  /* make sure dladdr is declared */
 # endif
-# define HAVE_DLINFO 1
 #endif
 
 #include <stdio.h>
@@ -79,8 +78,18 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
 #else
 
 #ifdef HAVE_DLFCN_H
-
-#include <dlfcn.h>
+# ifdef __osf__
+#  define __EXTENSIONS__
+# endif
+# include <dlfcn.h>
+# define HAVE_DLINFO 1
+# if defined(_AIX) || defined(__CYGWIN__) || \
+     defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
+     (defined(__osf__) && !defined(RTLD_NEXT))     || \
+     (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \
+       defined(__ANDROID__)
+#  undef HAVE_DLINFO
+# endif
 #endif
 
 /* Part of the hack in "dlfcn_load" ... */
@@ -134,7 +143,6 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
  * be hacked further relatively easily to deal with cases as we find
  * them. Initially this is to cope with OpenBSD. */
 #if defined(__OpenBSD__) || defined(__NetBSD__)
-#      define HAVE_DLINFO 1
 #      ifdef DL_LAZY
 #              define DLOPEN_FLAG DL_LAZY
 #      else
@@ -146,7 +154,6 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
 #      endif
 #else
 #      ifdef OPENSSL_SYS_SUNOS
-#              define HAVE_DLINFO 1
 #              define DLOPEN_FLAG 1
 #      else
 #              define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */
@@ -181,7 +188,7 @@ static int dlfcn_load(DSO *dso)
                ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
                goto err;
                }
-       if(!sk_push(dso->meth_data, (char *)ptr))
+       if(!sk_void_push(dso->meth_data, (char *)ptr))
                {
                DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
                goto err;
@@ -206,15 +213,15 @@ static int dlfcn_unload(DSO *dso)
                DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
                return(0);
                }
-       if(sk_num(dso->meth_data) < 1)
+       if(sk_void_num(dso->meth_data) < 1)
                return(1);
-       ptr = (void *)sk_pop(dso->meth_data);
+       ptr = sk_void_pop(dso->meth_data);
        if(ptr == NULL)
                {
                DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE);
                /* Should push the value back onto the stack in
                 * case of a retry. */
-               sk_push(dso->meth_data, (char *)ptr);
+               sk_void_push(dso->meth_data, ptr);
                return(0);
                }
        /* For now I'm not aware of any errors associated with dlclose() */
@@ -231,12 +238,12 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname)
                DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
                return(NULL);
                }
-       if(sk_num(dso->meth_data) < 1)
+       if(sk_void_num(dso->meth_data) < 1)
                {
                DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR);
                return(NULL);
                }
-       ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+       ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
        if(ptr == NULL)
                {
                DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE);
@@ -255,32 +262,35 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname)
 static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
        {
        void *ptr;
-       DSO_FUNC_TYPE sym, *tsym = &sym;
+       union {
+               DSO_FUNC_TYPE sym;
+               void *dlret;
+       } u;
 
        if((dso == NULL) || (symname == NULL))
                {
                DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
                return(NULL);
                }
-       if(sk_num(dso->meth_data) < 1)
+       if(sk_void_num(dso->meth_data) < 1)
                {
                DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR);
                return(NULL);
                }
-       ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+       ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
        if(ptr == NULL)
                {
                DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
                return(NULL);
                }
-       *(void **)(tsym) = dlsym(ptr, symname);
-       if(sym == NULL)
+       u.dlret = dlsym(ptr, symname);
+       if(u.dlret == NULL)
                {
                DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
                ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
                return(NULL);
                }
-       return(sym);
+       return u.sym;
        }
 
 static char *dlfcn_merger(DSO *dso, const char *filespec1,
@@ -349,6 +359,15 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
        return(merged);
        }
 
+#ifdef OPENSSL_SYS_MACOSX
+#define DSO_ext        ".dylib"
+#define DSO_extlen 6
+#else
+#define DSO_ext        ".so"
+#define DSO_extlen 3
+#endif
+
+
 static char *dlfcn_name_converter(DSO *dso, const char *filename)
        {
        char *translated;
@@ -359,8 +378,8 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
        transform = (strstr(filename, "/") == NULL);
        if(transform)
                {
-               /* We will convert this to "%s.so" or "lib%s.so" */
-               rsize += 3;     /* The length of ".so" */
+               /* We will convert this to "%s.so" or "lib%s.so" etc */
+               rsize += DSO_extlen;    /* The length of ".so" */
                if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
                        rsize += 3; /* The length of "lib" */
                }
@@ -374,9 +393,9 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
        if(transform)
                {
                if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
-                       sprintf(translated, "lib%s.so", filename);
+                       sprintf(translated, "lib%s" DSO_ext, filename);
                else
-                       sprintf(translated, "%s.so", filename);
+                       sprintf(translated, "%s" DSO_ext, filename);
                }
        else
                sprintf(translated, "%s", filename);
@@ -397,7 +416,6 @@ This is a quote from IRIX manual for dladdr(3c):
      intention to change this interface, so on a practical level, the code
      below is safe to use on IRIX.
 */
-#define HAVE_DLINFO 1
 #include <rld_interface.h>
 #ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
 #define _RLD_INTERFACE_DLFCN_H_DLADDR