# 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)