# New Ticket Created by  Dmitry Karasik 
# Please include the string:  [perl #40360]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=40360 >


dlopen(NULL,...) on linux returns NULL, and consequently dlsym(NULL,...) can be
used to access shared objects of the main executable. However, on freebsd
dlsym(NULL,...) server somewhat different purpose, and to access the main
executable dlsym(dlopen(NULL,...),...) must be used instead. The attached patch
corrects t/compilers/imcc/syn/pcc.t so it calls loadlib(NULL) for testing NCI
loadlib interface, and implements it in src/dynext.c.

diffstat:
 src/dynext.c               |   49 
 t/compilers/imcc/syn/pcc.t |    8 
 2 files changed, 40 insertions, 17 deletions

-- 
Sincerely,
        Dmitry Karasik

Index: src/dynext.c
===================================================================
--- src/dynext.c        (revision 14658)
+++ src/dynext.c        (working copy)
@@ -123,6 +123,18 @@
     PMC * const share_ext = VTABLE_get_pmc_keyed_int(interpreter, lib_paths, 
                                                      PARROT_LIB_DYN_EXTS);
 
+    if ( lib == NULL) {
+        *handle = Parrot_dlopen(NULL);
+        if (*handle) {
+            return "";
+        }
+        err = Parrot_dlerror();
+        Parrot_warn(interpreter, PARROT_WARNINGS_DYNEXT_FLAG,
+                    "Couldn't dlopen(NULL): %s\n",
+                    err ? err : "unknown reason");
+        return NULL;
+    }
+
     /*
      * first, try to add an extension to the file if it has none.
      */
@@ -260,19 +272,23 @@
      */
     Parrot_block_DOD(interpreter);
     /* get load_func */
-    load_func_name = Parrot_sprintf_c(interpreter, "Parrot_lib_%Ss_load",
-                                      lib_name);
-    cload_func_name = string_to_cstring(interpreter, load_func_name);
-    load_func = (PMC * (*)(Interp *))D2FPTR(Parrot_dlsym(handle,
-                cload_func_name));
-    string_cstring_free(cload_func_name);
-    /* get init_func */
-    init_func_name = Parrot_sprintf_c(interpreter, "Parrot_lib_%Ss_init",
-                                      lib_name);
-    cinit_func_name = string_to_cstring(interpreter, init_func_name);
-    init_func = (void (*)(Interp *, PMC *))D2FPTR(Parrot_dlsym(handle,
-                cinit_func_name));
-    string_cstring_free(cinit_func_name);
+    if ( lib_name != NULL) {
+        load_func_name = Parrot_sprintf_c(interpreter, "Parrot_lib_%Ss_load",
+                                          lib_name);
+        cload_func_name = string_to_cstring(interpreter, load_func_name);
+        load_func = (PMC * (*)(Interp *))D2FPTR(Parrot_dlsym(handle,
+                    cload_func_name));
+        string_cstring_free(cload_func_name);
+        /* get init_func */
+        init_func_name = Parrot_sprintf_c(interpreter, "Parrot_lib_%Ss_init",
+                                          lib_name);
+        cinit_func_name = string_to_cstring(interpreter, init_func_name);
+        init_func = (void (*)(Interp *, PMC *))D2FPTR(Parrot_dlsym(handle,
+                    cinit_func_name));
+        string_cstring_free(cinit_func_name);
+    } else {
+        load_func = init_func = NULL;
+    }
 
     lib_pmc = Parrot_init_lib(interpreter, load_func, init_func);
 
@@ -388,7 +404,12 @@
      *
      * LOCK()
      */
-    lib_name = parrot_split_path_ext(interpreter, lib, &wo_ext, &ext);
+    if ( lib == NULL) {
+        wo_ext = "";
+        lib_name = NULL;
+    } else {
+        lib_name = parrot_split_path_ext(interpreter, lib, &wo_ext, &ext);
+    }
     lib_pmc = is_loaded(interpreter, wo_ext);
     if (lib_pmc) {
        /* UNLOCK() */
Index: t/compilers/imcc/syn/pcc.t
===================================================================
--- t/compilers/imcc/syn/pcc.t  (revision 14658)
+++ t/compilers/imcc/syn/pcc.t  (working copy)
@@ -366,12 +366,14 @@
 OUT
 
 SKIP: {
-  skip("cant do NCI on $^O", 1) unless ($^O =~ /linux/ || $^O =~ /darwin/);
+  skip("cant do NCI on $^O", 1) unless ($^O =~ /linux|darwin|bsd/);
 pir_output_is(<<'CODE', <<'OUT', "nci");
 .sub test :main
-    .local pmc FABS, NULL
+    .local pmc FABS, LIB
+    .local string NULL
     null NULL
-    dlfunc FABS, NULL, "fabs", "dd"
+    LIB = loadlib NULL
+    dlfunc FABS, LIB, "fabs", "dd"
     .local float d, r
     d = -42
     r = FABS(d)

Reply via email to