hurricup has asked for the wisdom of the Perl Monks concerning the following question:
I'd like to extract an information about xsubs from dll/so files for my perl5 plugin project. I need names and prototypes if available. They are in there, but i don't know how to get them out.
So it's possible after all :) It's unfinished script I'll use, it's extracting all new typeglobs loaded in XS and using B::Deparse i can even get prototypes of subs:#!/usr/bin/perl use DynaLoader; use v5.10; use attributes(); my $MODULE_OF_INTEREST = $ARGV[0]; say STDERR "Trying to catch XSubs names from $MODULE_OF_INTEREST"; my $dl_install_xsub = \&DynaLoader::dl_install_xsub; my $frames = []; my $current_frame = $frames; *DynaLoader::dl_install_xsub = sub { my $bootstrap = $_[0]; if ($bootstrap =~ /^(.+?)::bootstrap/) { my $module = $1; say STDERR "Setting up $bootstrap"; my $original_bootstrap = eval {$dl_install_xsub->(@_)}; say STDERR "Real $bootstrap is $original_bootstrap"; *{$bootstrap} = sub { my $frame = { module => $module, frames => [], }; say STDERR sprintf "Bootstrapping $module";# from ".longme +ss; my $snapshot_before = get_typeglobs_snapshot(""); my $current_frame_backup = $current_frame; push @{$current_frame}, $frame; $current_frame = $frame->{frames}; my $bootstrap_result = eval {$original_bootstrap->(@_)}; say STDERR "Done..."; my $snapshot_after = get_typeglobs_snapshot(""); my %map = (); @map{@$snapshot_after} = @$snapshot_after; delete @map{@$snapshot_before}; $frame->{diff} = [keys %map]; say STDERR sprintf "Typeglob diff size: %s", scalar @{$fra +me->{diff}}; $current_frame = $current_frame_backup; return $bootstrap_result; }; say STDERR "Fake $bootstrap is ".\&{$bootstrap}; return \&{$bootstrap}; } else { say STDERR "$bootstrap is not looks like a bootstrap"; return $dl_install_xsub->(@_); } }; eval "use $MODULE_OF_INTEREST;"; if( my $e = $@ ) { die $e; } *DynaLoader::dl_install_xsub = \&$dl_install_xsub; require Data::Dumper; say Data::Dumper::Dumper($frames); sub get_typeglobs_snapshot { my $namespace = shift; my $recursion_map = shift // {qw/::main/}; $namespace =~ s/::$//; return [] if (exists $recursion_map->{$namespace}); $recursion_map->{$namespace} = 1; my $result = []; foreach my $name (keys %{"${namespace}::"}) { my $canonical_name = "${namespace}::$name"; if ($name =~ /::$/) { push @{$result}, @{get_typeglobs_snapshot($canonical_name, + $recursion_map)}; } else { push @{$result}, $canonical_name; } } return $result; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: extracting information about xsubs
by Anonymous Monk on Aug 19, 2015 at 03:46 UTC | |
by hurricup (Pilgrim) on Aug 19, 2015 at 03:58 UTC | |
by Anonymous Monk on Aug 19, 2015 at 04:14 UTC | |
by hurricup (Pilgrim) on Aug 19, 2015 at 04:55 UTC | |
by Corion (Patriarch) on Aug 19, 2015 at 07:45 UTC | |
| |
|
Re: extracting information about xsubs
by hurricup (Pilgrim) on Apr 28, 2016 at 15:20 UTC |