File: recursive_objdump.pl

package info (click to toggle)
libpar-packer-perl 1.064-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,388 kB
  • sloc: perl: 12,774; ansic: 1,474; makefile: 30; sh: 5
file content (67 lines) | stat: -rw-r--r-- 1,780 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!perl

use strict;
use warnings;
use File::Basename;
use Cwd;
use File::Spec;
use DynaLoader;

my $system_root = Cwd::abs_path($ENV{SystemRoot});

sub is_system_lib { Cwd::abs_path(shift) =~ m{^\Q$system_root\E/}i }

sub find_files_to_embed
{
    my ($par, $libperl) = @_;

    return recursive_objdump($par, dirname($^X));
}

sub recursive_objdump
{
    my ($path, @search_first_in) = @_;

    # NOTE: Looks like Perl on Windows (e.g. Strawberry) doesn't set 
    # $Config{ldlibpthname} - one could argue that its value should be "PATH".
    # But even where it is defined (e.g. "LD_LIBRARY_PATH" on Linux)
    # DynaLoader *appends* (an appropriately split)
    # $ENV{$Config{ldlibpthname}} to its search path, @dl_library_path, 
    # which is wrong in our context as we want it to be searched first.
    # Hence, provide our own value for @dl_library_path.
    local @DynaLoader::dl_library_path = (@search_first_in, File::Spec->path());

    my %dlls;
    my %seen;
    my $walker;
    $walker = sub 
    {
        my ($obj) = @_;
        return if $seen{lc $obj}++;

        my $out = qx(objdump -ax "$obj");
        die "objdump failed: $!\n" unless $? == 0;

        foreach my $dll ($out =~ /^\s*DLL Name:\s*(\S+)/gm)
        {
            next if $dlls{lc $dll};             # already found

            my ($file) = DynaLoader::dl_findfile($dll) or next;
            $dlls{lc $dll} = $file;

            next if is_system_lib($file);       # no need to recurse on a system library
            $walker->($file);                   # recurse
        }
    };
    $walker->(Cwd::abs_path($path));

    # weed out system libraries
    foreach my $name (keys %dlls)
    {
        delete $dlls{$name} if is_system_lib($dlls{$name});
    }
        
    return \%dlls;
}

1;