Rashed Abdel-Tawab | 4db47f4 | 2019-09-06 10:38:22 -0700 | [diff] [blame] | 1 | # Generated from DynaLoader_pm.PL, this file is unique for every OS |
| 2 | |
| 3 | package DynaLoader; |
| 4 | |
| 5 | # And Gandalf said: 'Many folk like to know beforehand what is to |
| 6 | # be set on the table; but those who have laboured to prepare the |
| 7 | # feast like to keep their secret; for wonder makes the words of |
| 8 | # praise louder.' |
| 9 | |
| 10 | # (Quote from Tolkien suggested by Anno Siegel.) |
| 11 | # |
| 12 | # See pod text at end of file for documentation. |
| 13 | # See also ext/DynaLoader/README in source tree for other information. |
| 14 | # |
| 15 | # Tim.Bunce@ig.co.uk, August 1994 |
| 16 | |
| 17 | BEGIN { |
| 18 | $VERSION = '1.42'; |
| 19 | } |
| 20 | |
| 21 | use Config; |
| 22 | |
| 23 | # enable debug/trace messages from DynaLoader perl code |
| 24 | $dl_debug = $ENV{PERL_DL_DEBUG} || 0 unless defined $dl_debug; |
| 25 | |
| 26 | # |
| 27 | # Flags to alter dl_load_file behaviour. Assigned bits: |
| 28 | # 0x01 make symbols available for linking later dl_load_file's. |
| 29 | # (only known to work on Solaris 2 using dlopen(RTLD_GLOBAL)) |
| 30 | # (ignored under VMS; effect is built-in to image linking) |
| 31 | # (ignored under Android; the linker always uses RTLD_LOCAL) |
| 32 | # |
| 33 | # This is called as a class method $module->dl_load_flags. The |
| 34 | # definition here will be inherited and result on "default" loading |
| 35 | # behaviour unless a sub-class of DynaLoader defines its own version. |
| 36 | # |
| 37 | |
| 38 | sub dl_load_flags { 0x00 } |
| 39 | |
| 40 | ($dl_dlext, $dl_so, $dlsrc) = @Config::Config{qw(dlext so dlsrc)}; |
| 41 | |
| 42 | $do_expand = 0; |
| 43 | |
| 44 | @dl_require_symbols = (); # names of symbols we need |
| 45 | @dl_library_path = (); # path to look for files |
| 46 | |
| 47 | #XSLoader.pm may have added elements before we were required |
| 48 | #@dl_shared_objects = (); # shared objects for symbols we have |
| 49 | #@dl_librefs = (); # things we have loaded |
| 50 | #@dl_modules = (); # Modules we have loaded |
| 51 | |
| 52 | # Initialise @dl_library_path with the 'standard' library path |
| 53 | # for this platform as determined by Configure. |
| 54 | |
| 55 | push(@dl_library_path, split(' ', $Config::Config{libpth})); |
| 56 | |
| 57 | my $ldlibpthname = $Config::Config{ldlibpthname}; |
| 58 | my $ldlibpthname_defined = defined $Config::Config{ldlibpthname}; |
| 59 | my $pthsep = $Config::Config{path_sep}; |
| 60 | |
| 61 | # Add to @dl_library_path any extra directories we can gather from environment |
| 62 | # during runtime. |
| 63 | |
| 64 | if ($ldlibpthname_defined && |
| 65 | exists $ENV{$ldlibpthname}) { |
| 66 | push(@dl_library_path, split(/$pthsep/, $ENV{$ldlibpthname})); |
| 67 | } |
| 68 | |
| 69 | # E.g. HP-UX supports both its native SHLIB_PATH *and* LD_LIBRARY_PATH. |
| 70 | |
| 71 | if ($ldlibpthname_defined && |
| 72 | $ldlibpthname ne 'LD_LIBRARY_PATH' && |
| 73 | exists $ENV{LD_LIBRARY_PATH}) { |
| 74 | push(@dl_library_path, split(/$pthsep/, $ENV{LD_LIBRARY_PATH})); |
| 75 | } |
| 76 | |
| 77 | # No prizes for guessing why we don't say 'bootstrap DynaLoader;' here. |
| 78 | # NOTE: All dl_*.xs (including dl_none.xs) define a dl_error() XSUB |
| 79 | boot_DynaLoader('DynaLoader') if defined(&boot_DynaLoader) && |
| 80 | !defined(&dl_error); |
| 81 | |
| 82 | if ($dl_debug) { |
| 83 | print STDERR "DynaLoader.pm loaded (@INC, @dl_library_path)\n"; |
| 84 | print STDERR "DynaLoader not linked into this perl\n" |
| 85 | unless defined(&boot_DynaLoader); |
| 86 | } |
| 87 | |
| 88 | 1; # End of main code |
| 89 | |
| 90 | sub croak { require Carp; Carp::croak(@_) } |
| 91 | |
| 92 | sub bootstrap_inherit { |
| 93 | my $module = $_[0]; |
| 94 | local *isa = *{"$module\::ISA"}; |
| 95 | local @isa = (@isa, 'DynaLoader'); |
| 96 | # Cannot goto due to delocalization. Will report errors on a wrong line? |
| 97 | bootstrap(@_); |
| 98 | } |
| 99 | |
| 100 | sub bootstrap { |
| 101 | # use local vars to enable $module.bs script to edit values |
| 102 | local(@args) = @_; |
| 103 | local($module) = $args[0]; |
| 104 | local(@dirs, $file); |
| 105 | |
| 106 | unless ($module) { |
| 107 | require Carp; |
| 108 | Carp::confess("Usage: DynaLoader::bootstrap(module)"); |
| 109 | } |
| 110 | |
| 111 | # A common error on platforms which don't support dynamic loading. |
| 112 | # Since it's fatal and potentially confusing we give a detailed message. |
| 113 | croak("Can't load module $module, dynamic loading not available in this perl.\n". |
| 114 | " (You may need to build a new perl executable which either supports\n". |
| 115 | " dynamic loading or has the $module module statically linked into it.)\n") |
| 116 | unless defined(&dl_load_file); |
| 117 | |
| 118 | |
| 119 | my @modparts = split(/::/,$module); |
| 120 | my $modfname = $modparts[-1]; |
| 121 | my $modfname_orig = $modfname; # For .bs file search |
| 122 | |
| 123 | # Some systems have restrictions on files names for DLL's etc. |
| 124 | # mod2fname returns appropriate file base name (typically truncated) |
| 125 | # It may also edit @modparts if required. |
| 126 | $modfname = &mod2fname(\@modparts) if defined &mod2fname; |
| 127 | |
| 128 | |
| 129 | |
| 130 | my $modpname = join('/',@modparts); |
| 131 | |
| 132 | print STDERR "DynaLoader::bootstrap for $module ", |
| 133 | "(auto/$modpname/$modfname.$dl_dlext)\n" |
| 134 | if $dl_debug; |
| 135 | |
| 136 | my $dir; |
| 137 | foreach (@INC) { |
| 138 | |
| 139 | $dir = "$_/auto/$modpname"; |
| 140 | |
| 141 | next unless -d $dir; # skip over uninteresting directories |
| 142 | |
| 143 | # check for common cases to avoid autoload of dl_findfile |
| 144 | my $try = "$dir/$modfname.$dl_dlext"; |
| 145 | last if $file = ($do_expand) ? dl_expandspec($try) : ((-f $try) && $try); |
| 146 | |
| 147 | # no luck here, save dir for possible later dl_findfile search |
| 148 | push @dirs, $dir; |
| 149 | } |
| 150 | # last resort, let dl_findfile have a go in all known locations |
| 151 | $file = dl_findfile(map("-L$_",@dirs,@INC), $modfname) unless $file; |
| 152 | |
| 153 | croak("Can't locate loadable object for module $module in \@INC (\@INC contains: @INC)") |
| 154 | unless $file; # wording similar to error from 'require' |
| 155 | |
| 156 | |
| 157 | my $bootname = "boot_$module"; |
| 158 | $bootname =~ s/\W/_/g; |
| 159 | @dl_require_symbols = ($bootname); |
| 160 | |
| 161 | # Execute optional '.bootstrap' perl script for this module. |
| 162 | # The .bs file can be used to configure @dl_resolve_using etc to |
| 163 | # match the needs of the individual module on this architecture. |
| 164 | # N.B. The .bs file does not following the naming convention used |
| 165 | # by mod2fname. |
| 166 | my $bs = "$dir/$modfname_orig"; |
| 167 | $bs =~ s/(\.\w+)?(;\d*)?$/\.bs/; # look for .bs 'beside' the library |
| 168 | if (-s $bs) { # only read file if it's not empty |
| 169 | print STDERR "BS: $bs ($^O, $dlsrc)\n" if $dl_debug; |
| 170 | eval { local @INC = ('.'); do $bs; }; |
| 171 | warn "$bs: $@\n" if $@; |
| 172 | } |
| 173 | |
| 174 | my $boot_symbol_ref; |
| 175 | |
| 176 | |
| 177 | |
| 178 | # Many dynamic extension loading problems will appear to come from |
| 179 | # this section of code: XYZ failed at line 123 of DynaLoader.pm. |
| 180 | # Often these errors are actually occurring in the initialisation |
| 181 | # C code of the extension XS file. Perl reports the error as being |
| 182 | # in this perl code simply because this was the last perl code |
| 183 | # it executed. |
| 184 | |
| 185 | my $flags = $module->dl_load_flags; |
| 186 | |
| 187 | my $libref = dl_load_file($file, $flags) or |
| 188 | croak("Can't load '$file' for module $module: ".dl_error()); |
| 189 | |
| 190 | push(@dl_librefs,$libref); # record loaded object |
| 191 | |
| 192 | $boot_symbol_ref = dl_find_symbol($libref, $bootname) or |
| 193 | croak("Can't find '$bootname' symbol in $file\n"); |
| 194 | |
| 195 | push(@dl_modules, $module); # record loaded module |
| 196 | |
| 197 | boot: |
| 198 | my $xs = dl_install_xsub("${module}::bootstrap", $boot_symbol_ref, $file); |
| 199 | |
| 200 | # See comment block above |
| 201 | |
| 202 | push(@dl_shared_objects, $file); # record files loaded |
| 203 | |
| 204 | &$xs(@args); |
| 205 | } |
| 206 | |
| 207 | sub dl_findfile { |
| 208 | # This function does not automatically consider the architecture |
| 209 | # or the perl library auto directories. |
| 210 | my (@args) = @_; |
| 211 | my (@dirs, $dir); # which directories to search |
| 212 | my (@found); # full paths to real files we have found |
| 213 | #my $dl_ext= 'so'; # $Config::Config{'dlext'} suffix for perl extensions |
| 214 | #my $dl_so = 'so'; # $Config::Config{'so'} suffix for shared libraries |
| 215 | |
| 216 | print STDERR "dl_findfile(@args)\n" if $dl_debug; |
| 217 | |
| 218 | # accumulate directories but process files as they appear |
| 219 | arg: foreach(@args) { |
| 220 | # Special fast case: full filepath requires no search |
| 221 | |
| 222 | |
| 223 | if (m:/: && -f $_) { |
| 224 | push(@found,$_); |
| 225 | last arg unless wantarray; |
| 226 | next; |
| 227 | } |
| 228 | |
| 229 | |
| 230 | # Deal with directories first: |
| 231 | # Using a -L prefix is the preferred option (faster and more robust) |
| 232 | if (m:^-L:) { s/^-L//; push(@dirs, $_); next; } |
| 233 | |
| 234 | # Otherwise we try to try to spot directories by a heuristic |
| 235 | # (this is a more complicated issue than it first appears) |
| 236 | if (m:/: && -d $_) { push(@dirs, $_); next; } |
| 237 | |
| 238 | |
| 239 | |
| 240 | # Only files should get this far... |
| 241 | my(@names, $name); # what filenames to look for |
| 242 | if (m:-l: ) { # convert -lname to appropriate library name |
| 243 | s/-l//; |
| 244 | push(@names,"lib$_.$dl_so"); |
| 245 | push(@names,"lib$_.a"); |
| 246 | } else { # Umm, a bare name. Try various alternatives: |
| 247 | # these should be ordered with the most likely first |
| 248 | push(@names,"$_.$dl_dlext") unless m/\.$dl_dlext$/o; |
| 249 | push(@names,"$_.$dl_so") unless m/\.$dl_so$/o; |
| 250 | |
| 251 | push(@names,"lib$_.$dl_so") unless m:/:; |
| 252 | push(@names, $_); |
| 253 | } |
| 254 | my $dirsep = '/'; |
| 255 | |
| 256 | foreach $dir (@dirs, @dl_library_path) { |
| 257 | next unless -d $dir; |
| 258 | |
| 259 | foreach $name (@names) { |
| 260 | my($file) = "$dir$dirsep$name"; |
| 261 | print STDERR " checking in $dir for $name\n" if $dl_debug; |
| 262 | $file = ($do_expand) ? dl_expandspec($file) : (-f $file && $file); |
| 263 | #$file = _check_file($file); |
| 264 | if ($file) { |
| 265 | push(@found, $file); |
| 266 | next arg; # no need to look any further |
| 267 | } |
| 268 | } |
| 269 | } |
| 270 | } |
| 271 | if ($dl_debug) { |
| 272 | foreach(@dirs) { |
| 273 | print STDERR " dl_findfile ignored non-existent directory: $_\n" unless -d $_; |
| 274 | } |
| 275 | print STDERR "dl_findfile found: @found\n"; |
| 276 | } |
| 277 | return $found[0] unless wantarray; |
| 278 | @found; |
| 279 | } |
| 280 | |
| 281 | sub dl_expandspec { |
| 282 | my($spec) = @_; |
| 283 | # Optional function invoked if DynaLoader.pm sets $do_expand. |
| 284 | # Most systems do not require or use this function. |
| 285 | # Some systems may implement it in the dl_*.xs file in which case |
| 286 | # this Perl version should be excluded at build time. |
| 287 | |
| 288 | # This function is designed to deal with systems which treat some |
| 289 | # 'filenames' in a special way. For example VMS 'Logical Names' |
| 290 | # (something like unix environment variables - but different). |
| 291 | # This function should recognise such names and expand them into |
| 292 | # full file paths. |
| 293 | # Must return undef if $spec is invalid or file does not exist. |
| 294 | |
| 295 | my $file = $spec; # default output to input |
| 296 | |
| 297 | return undef unless -f $file; |
| 298 | print STDERR "dl_expandspec($spec) => $file\n" if $dl_debug; |
| 299 | $file; |
| 300 | } |
| 301 | |
| 302 | sub dl_find_symbol_anywhere |
| 303 | { |
| 304 | my $sym = shift; |
| 305 | my $libref; |
| 306 | foreach $libref (@dl_librefs) { |
| 307 | my $symref = dl_find_symbol($libref,$sym,1); |
| 308 | return $symref if $symref; |
| 309 | } |
| 310 | return undef; |
| 311 | } |
| 312 | |
| 313 | __END__ |
| 314 | |