Skip to content

Commit

Permalink
DynaLoader 1.36 dl_find_symbol add 3rd optional argument
Browse files Browse the repository at this point in the history
On Darwin DynaLoader::bootstrap tries dl_find_symbol first with libhandle 0,
to see if the shlib with the symbol is already loaded, e.g. with libc.
We do not want to store the dl_last_error information for this mostly
failing probe, so add an optional ign_err=0 argument.
Similar for dl_find_symbol_anywhere, which is expected to fail for all librefs.

Also support dl_last_error on symbian, as on all other platforms.

TonyC: fix bad XS
  • Loading branch information
Reini Urban authored and tonycoz committed Nov 10, 2015
1 parent 067cec4 commit fd46a70
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 39 deletions.
4 changes: 2 additions & 2 deletions ext/DynaLoader/DynaLoader_pm.PL
Expand Up @@ -376,7 +376,7 @@ sub bootstrap {
my $boot_symbol_ref;

<<$^O-eq-darwin>>
if ($boot_symbol_ref = dl_find_symbol(0, $bootname)) {
if ($boot_symbol_ref = dl_find_symbol(0, $bootname, 1)) {
goto boot; #extension library has already been loaded, e.g. darwin
}
<</$^O-eq-darwin>>
Expand Down Expand Up @@ -545,7 +545,7 @@ sub dl_find_symbol_anywhere
my $sym = shift;
my $libref;
foreach $libref (@dl_librefs) {
my $symref = dl_find_symbol($libref,$sym);
my $symref = dl_find_symbol($libref,$sym,1);
return $symref if $symref;
}
return undef;
Expand Down
12 changes: 7 additions & 5 deletions ext/DynaLoader/dl_aix.xs
Expand Up @@ -721,20 +721,22 @@ dl_unload_file(libref)
RETVAL

void
dl_find_symbol(libhandle, symbolname)
dl_find_symbol(libhandle, symbolname, ign_err=0)
void * libhandle
char * symbolname
int ign_err
PREINIT:
void *retv;
CODE:
DLDEBUG(2,PerlIO_printf(Perl_debug_log, "dl_find_symbol(handle=%x, symbol=%s)\n",
libhandle, symbolname));
retv = dlsym(libhandle, symbolname);
DLDEBUG(2,PerlIO_printf(Perl_debug_log, " symbolref = %x\n", retv));
ST(0) = sv_newmortal() ;
if (retv == NULL)
SaveError(aTHX_ "%s",dlerror()) ;
else
ST(0) = sv_newmortal();
if (retv == NULL) {
if (!ign_err)
SaveError(aTHX_ "%s", dlerror());
} else
sv_setiv( ST(0), PTR2IV(retv));


Expand Down
7 changes: 4 additions & 3 deletions ext/DynaLoader/dl_dllload.xs
Expand Up @@ -141,9 +141,10 @@ dl_unload_file(libref)


void
dl_find_symbol(libhandle, symbolname)
dl_find_symbol(libhandle, symbolname, ign_err=0)
void * libhandle
char * symbolname
int ign_err
PREINIT:
void *retv;
PPCODE:
Expand All @@ -154,9 +155,9 @@ dl_find_symbol(libhandle, symbolname)
retv = dllqueryvar(libhandle, symbolname);
DLDEBUG(2, PerlIO_printf(Perl_debug_log,
" symbolref = %lx\n", (unsigned long) retv));
ST(0) = sv_newmortal() ;
ST(0) = sv_newmortal();
if (retv == NULL)
SaveError(aTHX_ "%s",strerror(errno)) ;
if (!ign_err) SaveError(aTHX_ "%s", strerror(errno));
else
sv_setiv( ST(0), PTR2IV(retv));
XSRETURN(1);
Expand Down
13 changes: 8 additions & 5 deletions ext/DynaLoader/dl_dlopen.xs
Expand Up @@ -12,6 +12,7 @@
* basic FreeBSD support, removed ClearError
* 29th February 2000 - Alan Burlison: Added functionality to close dlopen'd
* files when the interpreter exits
* 2015-03-12 - rurban: Added optional 3rd dl_find_symbol argument
*
*/

Expand Down Expand Up @@ -217,9 +218,10 @@ dl_unload_file(libref)


void
dl_find_symbol(libhandle, symbolname)
dl_find_symbol(libhandle, symbolname, ign_err=0)
void * libhandle
char * symbolname
int ign_err
PREINIT:
void *sym;
CODE:
Expand All @@ -232,10 +234,11 @@ dl_find_symbol(libhandle, symbolname)
sym = dlsym(libhandle, symbolname);
DLDEBUG(2, PerlIO_printf(Perl_debug_log,
" symbolref = %lx\n", (unsigned long) sym));
ST(0) = sv_newmortal() ;
if (sym == NULL)
SaveError(aTHX_ "%s",dlerror()) ;
else
ST(0) = sv_newmortal();
if (sym == NULL) {
if (!ign_err)
SaveError(aTHX_ "%s", dlerror());
} else
sv_setiv( ST(0), PTR2IV(sym));


Expand Down
10 changes: 6 additions & 4 deletions ext/DynaLoader/dl_dyld.xs
Expand Up @@ -174,9 +174,10 @@ dl_load_file(filename, flags=0)


void *
dl_find_symbol(libhandle, symbolname)
dl_find_symbol(libhandle, symbolname, ign_err=0)
void * libhandle
char * symbolname
int ign_err
CODE:
symbolname = Perl_form_nocontext("_%s", symbolname);
DLDEBUG(2, PerlIO_printf(Perl_debug_log,
Expand All @@ -186,9 +187,10 @@ dl_find_symbol(libhandle, symbolname)
DLDEBUG(2, PerlIO_printf(Perl_debug_log,
" symbolref = %lx\n", (unsigned long) RETVAL));
ST(0) = sv_newmortal() ;
if (RETVAL == NULL)
SaveError(aTHX_ "%s",dlerror()) ;
else
if (RETVAL == NULL) {
if (!ign_err)
SaveError(aTHX_ "%s",dlerror()) ;
} else
sv_setiv( ST(0), PTR2IV(RETVAL) );


Expand Down
10 changes: 6 additions & 4 deletions ext/DynaLoader/dl_freemint.xs
Expand Up @@ -144,9 +144,10 @@ haverror:


void
dl_find_symbol(libhandle, symbolname)
dl_find_symbol(libhandle, symbolname, ign_err=0)
void * libhandle
char * symbolname
int ign_err
PREINIT:
void *retv;
CODE:
Expand All @@ -155,9 +156,10 @@ dl_find_symbol(libhandle, symbolname)
retv = (void *)dld_get_func(symbolname);
DLDEBUG(2,PerlIO_printf(Perl_debug_log, " symbolref = %x\n", (unsigned int)retv));
ST(0) = sv_newmortal() ;
if (retv == NULL)
SaveError(aTHX_ "dl_find_symbol: Unable to find '%s' symbol", symbolname) ;
else
if (retv == NULL) {
if (!ign_err)
SaveError(aTHX_ "dl_find_symbol: Unable to find '%s' symbol", symbolname) ;
} else
sv_setiv(ST(0), PTR2IV(retv));
XSRETURN(1);

Expand Down
5 changes: 3 additions & 2 deletions ext/DynaLoader/dl_hpux.xs
Expand Up @@ -118,9 +118,10 @@ dl_unload_file(libref)


void
dl_find_symbol(libhandle, symbolname)
dl_find_symbol(libhandle, symbolname, ign_err=0)
void * libhandle
char * symbolname
int ign_err
PREINIT:
shl_t obj = (shl_t) libhandle;
void *symaddr = NULL;
Expand All @@ -145,7 +146,7 @@ dl_find_symbol(libhandle, symbolname)
}

if (status == -1) {
SaveError(aTHX_ "%s",(errno) ? Strerror(errno) : "Symbol not found") ;
if (!ign_err) SaveError(aTHX_ "%s",(errno) ? Strerror(errno) : "Symbol not found") ;
} else {
sv_setiv( ST(0), PTR2IV(symaddr) );
}
Expand Down
15 changes: 9 additions & 6 deletions ext/DynaLoader/dl_symbian.xs
Expand Up @@ -163,8 +163,8 @@ dl_load_file(filename, flags=0)
if (h && h->error == KErrNone)
sv_setiv(ST(0), PTR2IV(h));
else
PerlIO_printf(Perl_debug_log, "(dl_load_file %s %d)",
filename, h ? h->error : -1);
SaveError(aTHX_ "(dl_load_file %s %d)"
filename, h ? h->error : -1);
}


Expand All @@ -178,20 +178,23 @@ dl_unload_file(libhandle)


void
dl_find_symbol(libhandle, symbolname)
dl_find_symbol(libhandle, symbolname, ign_err=0)
void * libhandle
char * symbolname
int ign_err
PREINIT:
void *sym;
CODE:
PerlSymbianLibHandle* h = (PerlSymbianLibHandle*)libhandle;
sym = dlsym(libhandle, symbolname);
ST(0) = sv_newmortal();
if (sym)
if (sym) {
sv_setiv(ST(0), PTR2IV(sym));
else
PerlIO_printf(Perl_debug_log, "(dl_find_symbol %s %d)",
} else {
if (!ign_err)
SaveError(aTHX_ "(dl_find_symbol %s %d)",
symbolname, h ? h->error : -1);
}


void
Expand Down
5 changes: 3 additions & 2 deletions ext/DynaLoader/dl_vms.xs
Expand Up @@ -301,9 +301,10 @@ dl_load_file(filename, flags=0)


void
dl_find_symbol(librefptr,symname)
dl_find_symbol(librefptr,symname,ign_err=0)
void * librefptr
SV * symname
int ign_err
PREINIT:
struct libref thislib = *((struct libref *)librefptr);
struct dsc$descriptor_s
Expand All @@ -321,7 +322,7 @@ dl_find_symbol(librefptr,symname)
DLDEBUG(2,PerlIO_printf(Perl_debug_log, "\tentry point is %d\n",
(unsigned long int) entry));
if (!(sts & 1)) {
dl_set_error(sts,0);
if (!ign_err) dl_set_error(sts,0);
ST(0) = &PL_sv_undef;
}
else ST(0) = sv_2mortal(newSViv(PTR2IV(entry)));
Expand Down
12 changes: 6 additions & 6 deletions ext/DynaLoader/dl_win32.xs
Expand Up @@ -157,21 +157,21 @@ dl_unload_file(libref)
RETVAL

void
dl_find_symbol(libhandle, symbolname)
dl_find_symbol(libhandle, symbolname, ign_err=0)
void * libhandle
char * symbolname
int ign_err
PREINIT:
void *retv;
CODE:
DLDEBUG(2,PerlIO_printf(Perl_debug_log,"dl_find_symbol(handle=%x, symbol=%s)\n",
libhandle, symbolname));
retv = (void*) GetProcAddress((HINSTANCE) libhandle, symbolname);
DLDEBUG(2,PerlIO_printf(Perl_debug_log," symbolref = %x\n", retv));
ST(0) = sv_newmortal() ;
if (retv == NULL)
SaveError(aTHX_ "find_symbol:%s",
OS_Error_String(aTHX)) ;
else
ST(0) = sv_newmortal();
if (retv == NULL) {
if (!ign_err) SaveError(aTHX_ "find_symbol:%s", OS_Error_String(aTHX));
} else
sv_setiv( ST(0), (IV)retv);


Expand Down

0 comments on commit fd46a70

Please sign in to comment.