#ifdef DSO_DLFCN
+# define DSO_DSOBYADDR "DSO_dsobyaddr"
+# define DSO_FREE "DSO_free"
+
+typedef void DSO;
+typedef DSO * (*DSO_dsobyaddr_t)(void (*addr)(), int flags);
+typedef int (*DSO_free_t)(DSO *dso);
+
+static DSO_dsobyaddr_t DSO_dsobyaddr;
+static DSO_free_t DSO_free;
+
# include <dlfcn.h>
typedef void * SHLIB;
# define CRYPTO_FIRST_OPT "-crypto_first"
# define SSL_FIRST_OPT "-ssl_first"
# define JUST_CRYPTO_OPT "-just_crypto"
+# define DSO_REFTEST_OPT "-dso_ref"
enum test_types_en {
CRYPTO_FIRST,
SSL_FIRST,
- JUST_CRYPTO
+ JUST_CRYPTO,
+ DSO_REFTEST
};
int main(int argc, char **argv)
void (*func) (void);
SHLIB_SYM sym;
} tls_method_sym, ssl_ctx_new_sym, ssl_ctx_free_sym, err_get_error_sym,
- openssl_version_num_sym;
+ openssl_version_num_sym, dso_dsobyaddr_sym, dso_free_sym;
enum test_types_en test_type;
int i;
test_type = SSL_FIRST;
} else if (strcmp(argv[1], JUST_CRYPTO_OPT) == 0) {
test_type = JUST_CRYPTO;
+ } else if (strcmp(argv[1], DSO_REFTEST_OPT) == 0) {
+ test_type = DSO_REFTEST;
} else {
printf("Unrecognised argument\n");
return 1;
for (i = 0; i < 2; i++) {
if ((i == 0 && (test_type == CRYPTO_FIRST
- || test_type == JUST_CRYPTO))
+ || test_type == JUST_CRYPTO
+ || test_type == DSO_REFTEST))
|| (i == 1 && test_type == SSL_FIRST)) {
if (!shlib_load(argv[2], &cryptolib)) {
printf("Unable to load libcrypto\n");
}
}
- if (test_type != JUST_CRYPTO) {
+ if (test_type != JUST_CRYPTO && test_type != DSO_REFTEST) {
if (!shlib_sym(ssllib, TLS_METHOD, &tls_method_sym.sym)
|| !shlib_sym(ssllib, SSL_CTX_NEW, &ssl_ctx_new_sym.sym)
|| !shlib_sym(ssllib, SSL_CTX_FREE, &ssl_ctx_free_sym.sym)) {
return 1;
}
+ if (test_type == DSO_REFTEST) {
+# ifdef DSO_DLFCN
+ /*
+ * This is resembling the code used in ossl_init_base() and
+ * OPENSSL_atexit() to block unloading the library after dlclose().
+ * We are not testing this on Windows, because it is done there in a
+ * completely different way. Especially as a call to DSO_dsobyaddr()
+ * will always return an error, because DSO_pathbyaddr() is not
+ * implemented there.
+ */
+ if (!shlib_sym(cryptolib, DSO_DSOBYADDR, &dso_dsobyaddr_sym.sym)
+ || !shlib_sym(cryptolib, DSO_FREE, &dso_free_sym.sym)) {
+ printf("Unable to load crypto dso symbols\n");
+ return 1;
+ }
+
+ DSO_dsobyaddr = (DSO_dsobyaddr_t)dso_dsobyaddr_sym.func;
+ DSO_free = (DSO_free_t)dso_free_sym.func;
+
+ {
+ DSO *hndl;
+ /* use known symbol from crypto module */
+ if ((hndl = DSO_dsobyaddr((void (*)())ERR_get_error, 0)) != NULL) {
+ DSO_free(hndl);
+ } else {
+ printf("Unable to obtain DSO reference from crypto symbol\n");
+ return 1;
+ }
+ }
+# endif /* DSO_DLFCN */
+ }
+
for (i = 0; i < 2; i++) {
if ((i == 0 && test_type == CRYPTO_FIRST)
|| (i == 1 && test_type == SSL_FIRST)) {
}
}
if ((i == 0 && (test_type == SSL_FIRST
- || test_type == JUST_CRYPTO))
+ || test_type == JUST_CRYPTO
+ || test_type == DSO_REFTEST))
|| (i == 1 && test_type == CRYPTO_FIRST)) {
if (!shlib_close(cryptolib)) {
printf("Unable to close libcrypto\n");