#!/usr/bin/env perl

#
#//===----------------------------------------------------------------------===//
#//
#//                     The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/lib";

use tools;
use Platform ":vars";

our $VERSION = "0.005";

# --------------------------------------------------------------------------------------------------
# Ouput parse error.
#     $tool -- Name of tool.
#     @bulk -- Output of the tool.
#     $n    -- Number of line caused parse error.
sub parse_error($\@$) {
    my ( $tool, $bulk, $n ) = @_;
    my @bulk;
    for ( my $i = 0; $i < @$bulk; ++ $i ) {
        push( @bulk, ( $i == $n ? ">>> " : "    " ) . $bulk->[ $i ] );
    }; # for $i
    runtime_error( "Fail to parse $tool output:", @bulk, "(eof)" );
}; # sub parse_error


# --------------------------------------------------------------------------------------------------
# Linux* OS version of get_deps() parses output of ldd:
#
# $ ldd libname.so
#   libc.so.6 => /lib64/libc.so.6 (0x00002b60fedd8000)
#   libdl.so.2 => /lib64/libdl.so.2 (0x00002b60ff12b000)
#   libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b60ff32f000)
#   /lib64/ld-linux-x86-64.so.2 (0x0000003879400000)
#
# Note: ldd printd all the dependencies, direct and indirect. (For example, if specified library
# requires libdl.so, and libdl.so requires /lib/ld-linux.so, ldd prints both libdl.so and
# /lib/ld-linux.so). If you do not want indirect dependencies, look at readelf tool.
#
sub get_deps_ldd($) {

    my $lib = shift ( @_ );
    my $tool = "ldd";
    my @bulk;
    my @deps;

    execute( [ $tool, $lib ], -stdout => \@bulk );
    debug( @bulk, "(eof)" );

    foreach my $i ( 0 .. @bulk - 1 ) {
        my $line = $bulk[ $i ];
        if ( $line !~ m{^\s*(?:([_a-z0-9.+-/]*)\s+=>\s+)?([_a-z0-9.+-/]*)\s+\(0x[0-9a-z]*\)$}i ) {
            parse_error( $tool, @bulk, $i );
        }; # if
        my $dep = ( defined( $1 ) ? $1 : $2 );
        push( @deps, $dep );
    }; # foreach $i

    return @deps;

}; # sub get_deps_ldd


# --------------------------------------------------------------------------------------------------
# Another Linux* OS version of get_deps() parses output of readelf:
#
# $ readelf -d exports/lin_32e/lib/libomp.so
#
# Dynamic segment at offset 0x87008 contains 24 entries:
#   Tag        Type                         Name/Value
#  0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
#  0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
#  0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
#  0x000000000000000e (SONAME)             Library soname: [libomp.so]
#  0x000000000000000d (FINI)               0x51caa
#  0x0000000000000004 (HASH)               0x158
#  0x0000000000000005 (STRTAB)             0x9350
#  ...
#
# Note: In contrast to ldd, readlef shows only direct dependencies.
#
sub get_deps_readelf($) {

    my $file = shift ( @_ );
    my $tool;
    my @bulk;
    my @deps;

    if($target_arch eq "mic") {
        $tool = "x86_64-k1om-linux-readelf";
    } else {
        $tool = "readelf";
    }

    # Force the readelf call to be in English. For example, when readelf
    # is called on a french localization, it will find "Librairie partagees"
    # instead of shared library
    $ENV{ LANG } = "C";

    execute( [ $tool, "-d", $file ], -stdout => \@bulk );
    debug( @bulk, "(eof)" );

    my $i = 0;
    # Parse header.
    ( $i < @bulk and $bulk[ $i ] =~ m{^\s*$} )
        or parse_error( $tool, @bulk, $i );
    ++ $i;
    if ( $i == @bulk - 1 and $bulk[ $i ] =~ m{^There is no dynamic section in this file\.\s*$} ) {
        # This is not dynamic executable => no dependencies.
        return @deps;
    }; # if
    ( $i < @bulk and $bulk[ $i ] =~ m{^Dynamic (?:segment|section) at offset 0x[0-9a-f]+ contains \d+ entries:\s*$} )
        or parse_error( $tool, @bulk, $i );
    ++ $i;
    ( $i < @bulk and $bulk[ $i ] =~ m{^\s*Tag\s+Type\s+Name/Value\s*$} )
        or parse_error( $tool, @bulk, $i );
    ++ $i;
    # Parse body.
    while ( $i < @bulk ) {
        my $line = $bulk[ $i ];
        if ( $line !~ m{^\s*0x[0-9a-f]+\s+\(([_A-Z0-9]+)\)\s+(.*)\s*$}i ) {
            parse_error( $tool, @bulk, $i );
        }; # if
        my ( $type, $value ) = ( $1, $2 );
        if ( $type eq "NEEDED" ) {
            if ( $value !~ m{\AShared library: \[(.*)\]\z} ) {
                parse_error( $tool, @bulk, $i );
            }; # if
            my $dep = $1;
            push( @deps, $dep );
        }; # if
        ++ $i;
    }; # foreach $i

    return @deps;

}; # sub get_deps_readelf


# --------------------------------------------------------------------------------------------------
# OS X* version of get_deps() parses output of otool:
#
# $ otool -L libname.dylib
# exports/mac_32/lib.thin/libomp.dylib:
#        libomp.dylib (compatibility version 5.0.0, current version 5.0.0)
#        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.1.3)
#
sub get_deps_otool($) {

    my $file = shift ( @_ );
    my $name = get_file( $file );
    my $tool = "otool";
    my @bulk;
    my @deps;

    if ( $target_arch eq "32e" ) {
        # On older (Tiger) systems otool does not recognize 64-bit binaries, so try to locate
        # otool64.
        my $path = which( "otool64" );
        if ( defined ( $path ) ) {
            $tool = "otool64";
        }; # if
    }; # if

    execute( [ $tool, "-L", $file ], -stdout => \@bulk );
    debug( @bulk, "(eof)" );

    my $i = 0;
    # Parse the first one or two lines separately.
    ( $i < @bulk and $bulk[ $i ] =~ m{^\Q$file\E:$} )
        or parse_error( $tool, @bulk, $i );
    ++ $i;
    if ( $name =~ m{\.dylib\z} ) {
        # In case of dynamic library otool print the library itself as a dependent library.
        ( $i < @bulk and $bulk[ $i ] =~ m{^\s+\Q$name\E\s+\(compatibility version.*\)$} )
            or parse_error( $tool, @bulk, $i );
        ++ $i;
    }; # if

    # Then parse the rest.
    while ( $i < @bulk ) {
        my $line = $bulk[ $i ];
        if ( $line !~ m/^\s*(.*)\s+\(compatibility version\s.*\)$/ ) {
            parse_error( $tool, @bulk, $i );
        }; # if
        my ( $dep ) = ( $1 );
        push( @deps, $dep );
        ++ $i;
    }; # while

    return @deps;

}; # sub get_deps_otool


# --------------------------------------------------------------------------------------------------
# Windows* OS version of get_deps() parses output of link:
#
# > link -dump -dependents libname.dll
# Microsoft (R) COFF/PE Dumper Version 8.00.40310.39
# Copyright (C) Microsoft Corporation.  All rights reserved.
# Dump of file S:\Projects.OMP\users\omalyshe\omp\libomp\exports\win_64\lib\libompmd.dll
# File Type: DLL
#   Image has the following dependencies:
#     KERNEL32.dll
#   Summary
#         C000 .data
#         6000 .pdata
#        18000 .rdata
#        ...
#
# > link -dump -directives libname.lib
# Microsoft (R) COFF/PE Dumper Version 8.00.40310.39
# Copyright (C) Microsoft Corporation.  All rights reserved.
# Dump of file S:\Projects.OMP\users\omalyshe\omp\libomp\exports\win_32e\lib\libimp5mt.lib
# File Type: LIBRARY
#   Linker Directives
#   -----------------
#   -defaultlib:"uuid.lib"
#   -defaultlib:"uuid.lib"
#   .....
#   Summary
#       3250 .bss
#       3FBC .data
#         34 .data1
#       ....
sub get_deps_link($) {

    my ( $lib ) = @_;
    my $tool = "link";
    my @bulk;
    my @deps;

    my $ext = lc( get_ext( $lib ) );
    if ( $ext !~ m{\A\.(?:lib|dll|exe)\z}i ) {
        runtime_error( "Incorrect file is specified: `$lib'; only `lib', `dll' or `exe' file expected" );
    }; # if

    execute(
        [ $tool, "/dump", ( $ext eq ".lib" ? "/directives" : "/dependents" ), $lib ],
        -stdout => \@bulk
    );

    debug( @bulk, "(eof)" );

    my $i = 0;
    ( $i < @bulk and $bulk[ $i ] =~ m{^Microsoft \(R\) COFF\/PE Dumper Version.*$} ) or parse_error( $tool, @bulk, $i ); ++ $i;
    ( $i < @bulk and $bulk[ $i ] =~ m{^Copyright \(C\) Microsoft Corporation\..*$} ) or parse_error( $tool, @bulk, $i ); ++ $i;
    ( $i < @bulk and $bulk[ $i ] =~ m{^\s*$}                                       ) or parse_error( $tool, @bulk, $i ); ++ $i;
    ( $i < @bulk and $bulk[ $i ] =~ m{^\s*$}                                       ) or parse_error( $tool, @bulk, $i ); ++ $i;
    ( $i < @bulk and $bulk[ $i ] =~ m{^Dump of file\s\Q$lib\E$}                    ) or parse_error( $tool, @bulk, $i ); ++ $i;
    ( $i < @bulk and $bulk[ $i ] =~ m{^\s*$}                                       ) or parse_error( $tool, @bulk, $i ); ++ $i;
    ( $i < @bulk and $bulk[ $i ] =~ m{^File Type:\s(.*)$}                          ) or parse_error( $tool, @bulk, $i ); ++ $i;
    ( $i < @bulk and $bulk[ $i ] =~ m{^\s*$}                                       ) or parse_error( $tool, @bulk, $i ); ++ $i;

    if ( $ext eq ".lib" ) {

        my %deps;
        while ( $i < @bulk ) {
            my $line = $bulk[ $i ];
            if ( 0 ) {
            } elsif ( $line =~ m{^\s*[-/]defaultlib\:(.*)\s*$}i ) {
                my $dep = $1;
                # Normalize library name:
                $dep = lc( $1 );              # Convert to lower case.
                $dep =~ s{\A"(.*)"\z}{$1};    # Drop surrounding quotes (if any).
                $dep =~ s{\.lib\z}{};         # Drop .lib suffix (if any).
                $deps{ $dep } = 1;
            } elsif ( $line =~ m{^\s*Linker Directives\s*$} ) {
            } elsif ( $line =~ m{^\s*-+\s*$} ) {
            } elsif ( $line =~ m{^\s*/alternatename\:.*$} ) {
            } elsif ( $line =~ m{^\s*$} ) {
            } elsif ( $line =~ m{^\s*/FAILIFMISMATCH\:.*$} ) {
                # This directive is produced only by _MSC_VER=1600
            } elsif ( $line =~ m{^\s*Summary\s*$} ) {
                last;
            } else {
                parse_error( $tool, @bulk, $i );
            }; # if
            ++ $i;
        } # while
        @deps = keys( %deps );

    } else {

        ( $i < @bulk and $bulk[ $i ] =~ m{\s*Image has the following dependencies\:$} )
            or parse_error( $tool, @bulk, $i );
        ++ $i;
        while ( $i < @bulk ) {
            my $line = $bulk[ $i ];
            if ( 0 ) {
            } elsif ( $line =~ m{^\s*$} ) {
                # Ignore empty lines.
            } elsif ( $line =~ m{^\s*(.*\.dll)$}i ) {
                my $dep = lc( $1 );
                push( @deps, $dep );
            } elsif ( $line =~ m{^\s*Summary$} ) {
                last;
            } else {
                parse_error( $tool, @bulk, $i );
            }; # if
            ++ $i;
        }; # while

    }; # if

    return @deps;

}; # sub get_deps_link


# --------------------------------------------------------------------------------------------------
# Main.
# --------------------------------------------------------------------------------------------------

# Parse command line.
my $expected;
my $bare;
Getopt::Long::Configure( "permute" );
get_options(
    Platform::target_options(),
    "bare"       => \$bare,
    "expected=s" => \$expected,
);
my @expected;
if ( defined( $expected ) ) {
    if ( $expected ne "none" ) {
        @expected = sort( split( ",", $expected ) );
        if ( $target_os eq "win" ) {
            @expected = map( lc( $_ ), @expected );
        }; # if
    }; # if
}; # if
if ( @ARGV < 1 ) {
    cmdline_error( "Specify a library name to check for dependencies" );
}; # if
if ( @ARGV > 1 ) {
    cmdline_error( "Too many arguments" );
}; # if
my $lib = shift( @ARGV );
if ( not -e $lib ){
    runtime_error( "Specified file does not exist: \"$lib\"" );
}; # if

# Select appropriate get_deps implementation.
if ( 0 ) {
} elsif ( $target_os eq "lin" ) {
    *get_deps = \*get_deps_readelf;
} elsif ( $target_os eq "mac" ) {
    *get_deps = \*get_deps_otool;
} elsif ( $target_os eq "win" ) {
    *get_deps = \*get_deps_link;
} else {
    runtime_error( "OS \"$target_os\" not supported" );
}; # if

# Do the work.
my @deps = sort( get_deps( $lib ) );
if ( $bare ) {
    print( map( "$_\n", @deps ) );
} else {
    info( "Dependencies:", @deps ? map( "    $_", @deps ) : "(none)" );
}; # if
if ( defined( $expected ) ) {
    my %deps = map( ( $_ => 1 ), @deps );
    foreach my $dep ( @expected ) {
        delete( $deps{ $dep } );
    }; # foreach
    my @unexpected = sort( keys( %deps ) );
    if ( @unexpected ) {
        runtime_error( "Unexpected dependencies:", map( "    $_", @unexpected ) );
    }; # if
}; # if

exit( 0 );

__END__

=pod

=head1 NAME

B<check-depends.pl> -- Check dependencies for a specified library.

=head1 SYNOPSIS

B<check-depends.pl> I<OPTIONS>... I<library>

=head1 DESCRIPTION

C<check-depends.pl> finds direct dependencies for a specified library. List of actual dependencies
is sorted alphabetically and printed. If list of expected dependencies is specified, the scripts
checks the library has only allowed dependencies. In case of not expected depndencies the script
issues error message and exits with non-zero code.

Linux* OS and OS X*: The script finds dependencies only for dymamic libraries. Windows* OS: The script
finds dependencies for either static or dymamic libraries.

The script uses external tools. On Linux* OS, it runs F<readelf>, on OS X* -- F<otool> (or F<otool64>),
on Windows* OS -- F<link>.

On Windows* OS dependencies are printed in lower case, case of expected dependencies ignored.

=head1 OPTIONS

=over

=item B<--bare>

Do not use fancy formatting; produce plain, bare output: just a list of libraries,
a library per line.

=item B<--expected=>I<list>

I<list> is comma-separated list of expected dependencies (or C<none>).
If C<--expected> option specified, C<check-depends.pl> checks the specified library
has only expected dependencies.

=item B<--os=>I<str>

Specify target OS (tool to use) manually.
Useful for cross-build, when host OS is not the same as target OS.
I<str> should be either C<lin>, C<mac>, or C<win>.

=back

=head2 Standard Options

=over

=item B<--help>

Print short help message and exit.

=item B<--doc>

=item B<--manual>

Print full documentation and exit.

=item B<--quiet>

Do not output informational messages.

=item B<--version>

Print version and exit.

=back

=head1 ARGUMENTS

=over

=item I<library>

A name of library to find or check dependencies.

=back

=head1 EXAMPLES

Just print library dependencies (Windows* OS):

    > check-depends.pl exports/win_32/lib/libompmd.dll
    check-depends.pl: (i) Dependencies:
    check-depends.pl: (i)     kernel32.dll

Print library dependencies, use bare output (Linux* OS):

    $ check-depends.pl --bare exports/lin_32e/lib/libomp_db.so
    libc.so.6
    libdl.so.2
    libpthread.so.0

Check the library does not have any dependencies (OS X*):

    $ check-depends.pl --expected=none exports/mac_32/lib/libomp.dylib
    check-depends.pl: (i) Dependencies:
    check-depends.pl: (i)     /usr/lib/libSystem.B.dylib
    check-depends.pl: (x) Unexpected dependencies:
    check-depends.pl: (x)     /usr/lib/libSystem.B.dylib
    $ echo $?
    2

=cut

# end of file #

