Home | History | Annotate | Line # | Download | only in cf
      1  1.1  elric ########################################################################
      2  1.1  elric #
      3  1.1  elric # Copyright (c) 2010, Secure Endpoints Inc.
      4  1.1  elric # All rights reserved.
      5  1.1  elric #
      6  1.1  elric # Redistribution and use in source and binary forms, with or without
      7  1.1  elric # modification, are permitted provided that the following conditions
      8  1.1  elric # are met:
      9  1.1  elric #
     10  1.1  elric # - Redistributions of source code must retain the above copyright
     11  1.1  elric #   notice, this list of conditions and the following disclaimer.
     12  1.1  elric #
     13  1.1  elric # - Redistributions in binary form must reproduce the above copyright
     14  1.1  elric #   notice, this list of conditions and the following disclaimer in
     15  1.1  elric #   the documentation and/or other materials provided with the
     16  1.1  elric #   distribution.
     17  1.1  elric #
     18  1.1  elric # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  1.1  elric # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  1.1  elric # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     21  1.1  elric # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     22  1.1  elric # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  1.1  elric # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     24  1.1  elric # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25  1.1  elric # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     26  1.1  elric # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  1.1  elric # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     28  1.1  elric # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  1.1  elric # POSSIBILITY OF SUCH DAMAGE.
     30  1.1  elric #
     31  1.1  elric 
     32  1.1  elric my $show_module_name = 1;
     33  1.1  elric my $use_indent = 1;
     34  1.1  elric my $strip_leading_underscore = 0;
     35  1.1  elric my $always_export = 0;
     36  1.1  elric my $module_name = "";
     37  1.1  elric my $local_prefix = "SHIM_";
     38  1.1  elric my %forward_exports = ();
     39  1.1  elric my %local_exports = ();
     40  1.1  elric 
     41  1.1  elric sub build_forwarder_target_list($)
     42  1.1  elric {
     43  1.1  elric     $fn = shift;
     44  1.1  elric 
     45  1.1  elric     print STDERR "Processing defs from file [$fn]\n";
     46  1.1  elric 
     47  1.1  elric     open(SP, '-|', "dumpbin /exports \"".$fn."\"") or die "Can't open pipe for $fn";
     48  1.1  elric 
     49  1.1  elric   LINE:
     50  1.1  elric     while (<SP>) {
     51  1.1  elric #        112   6F 00071CDC krb5_encrypt_size
     52  1.1  elric 
     53  1.1  elric 	/^ +([[:digit:]]+)\s+[[:xdigit:]]+\s[[:xdigit:]]{8,}\s+(\S+)(?:| = (\S*))$/ && do {
     54  1.1  elric 	    my ($ordinal, $symbol, $in) = ($1, $2, $3);
     55  1.1  elric 
     56  1.1  elric 	    if ($in eq "") { $in = $symbol };
     57  1.1  elric 	    $forward_exports{$symbol} = $in;
     58  1.1  elric 	};
     59  1.1  elric     }
     60  1.1  elric 
     61  1.1  elric     close SP;
     62  1.1  elric }
     63  1.1  elric 
     64  1.1  elric # Dump all symbols for the given dll file that are defined and have
     65  1.1  elric # external scope.
     66  1.1  elric 
     67  1.1  elric sub build_def_file($)
     68  1.1  elric {
     69  1.1  elric     $fn = shift;
     70  1.1  elric 
     71  1.1  elric     print STDERR "Opening dump of DLL [$fn]\n";
     72  1.1  elric 
     73  1.1  elric     open(SP, '-|', "dumpbin /exports \"".$fn."\"") or die "Can't open pipe for $fn";
     74  1.1  elric 
     75  1.1  elric   LINE:
     76  1.1  elric     while (<SP>) {
     77  1.1  elric #        112   6F 00071CDC krb5_encrypt_size
     78  1.1  elric 
     79  1.1  elric 	/^ +([[:digit:]]+)\s+[[:xdigit:]]+\s[[:xdigit:]]{8,}\s+(\S+)(?:| = (\S*))$/ && do {
     80  1.1  elric 	    my ($ordinal, $symbol, $in) = ($1, $2, $3);
     81  1.1  elric 
     82  1.1  elric 	    if ($strip_leading_underscore && $symbol =~ /_(.*)/) {
     83  1.1  elric 		$symbol = $1;
     84  1.1  elric 	    }
     85  1.1  elric 	    if (exists $local_exports{$symbol}) {
     86  1.1  elric 		print "\t".$symbol;
     87  1.1  elric 		print " = ".$local_exports{$symbol};
     88  1.1  elric 		if ($in ne $local_exports{$symbol} and $in ne "") {
     89  1.1  elric 		    print STDERR "Incorrect calling convention for local $symbol\n";
     90  1.1  elric 		    print STDERR "  ".$in." != ".$local_exports{$symbol}."\n";
     91  1.1  elric 		}
     92  1.1  elric 		print "\t@".$ordinal."\n";
     93  1.1  elric 	    } elsif (exists $local_exports{$local_prefix.$symbol}) {
     94  1.1  elric 		print "\t".$symbol;
     95  1.1  elric 		print " = ".$local_exports{$local_prefix.$symbol};
     96  1.1  elric 		print "\t@".$ordinal."\n";
     97  1.1  elric 	    } elsif (exists $forward_exports{$symbol}) {
     98  1.1  elric 		print "\t".$symbol;
     99  1.1  elric 		print " = ".$module_name;
    100  1.1  elric 		if ($in ne $forward_exports{$symbol} and $in ne "") {
    101  1.1  elric 		    print STDERR "Incorrect calling convention for $symbol\n";
    102  1.1  elric 		    print STDERR "  ".$in." != ".$forward_exports{$symbol}."\n";
    103  1.1  elric 		}
    104  1.1  elric 		my $texp = $forward_exports{$symbol};
    105  1.1  elric 		if ($texp =~ /^_([^@]+)$/) { $texp = $1; }
    106  1.1  elric 		print $texp."\t@".$ordinal."\n";
    107  1.1  elric 	    } elsif ($always_export) {
    108  1.1  elric                 print "\t".$symbol." = ".$local_prefix.$symbol;
    109  1.1  elric                 print "\t@".$ordinal."\n";
    110  1.1  elric             } else {
    111  1.1  elric 		print STDERR "Symbol not found: $symbol\n";
    112  1.1  elric 	    }
    113  1.1  elric 	};
    114  1.1  elric     }
    115  1.1  elric 
    116  1.1  elric     close SP;
    117  1.1  elric }
    118  1.1  elric 
    119  1.1  elric sub build_local_exports_list($)
    120  1.1  elric {
    121  1.1  elric     $fn = shift;
    122  1.1  elric 
    123  1.1  elric     print STDERR "Opening dump of object [$fn]\n";
    124  1.1  elric 
    125  1.1  elric     open(SP, '-|', "dumpbin /symbols \"".$fn."\"") or die "Can't open pipe for $fn";
    126  1.1  elric 
    127  1.1  elric   LINE:
    128  1.1  elric     while (<SP>) {
    129  1.1  elric 	# 009 00000010 SECT3  notype ()    External     | _remove_error_table@4
    130  1.1  elric 	m/^[[:xdigit:]]{3,}\s[[:xdigit:]]{8,}\s(\w+)\s+\w*\s+(?:\(\)|  )\s+(\w+)\s+\|\s+(\S+)$/ && do {
    131  1.1  elric 	    my ($section, $visibility, $symbol) = ($1, $2, $3);
    132  1.1  elric 
    133  1.1  elric 	    if ($section ne "UNDEF" && $visibility eq "External") {
    134  1.1  elric 
    135  1.1  elric 		my $exp_name = $symbol;
    136  1.1  elric 
    137  1.1  elric 		if ($symbol =~ m/^_(\w+)(?:@.*|)$/) {
    138  1.1  elric 		    $exp_name = $1;
    139  1.1  elric 		}
    140  1.1  elric 
    141  1.1  elric 		if ($symbol =~ m/^_([^@]+)$/) {
    142  1.1  elric 		    $symbol = $1;
    143  1.1  elric 		}
    144  1.1  elric 
    145  1.1  elric 		$local_exports{$exp_name} = $symbol;
    146  1.1  elric 	    }
    147  1.1  elric 	};
    148  1.1  elric     }
    149  1.1  elric 
    150  1.1  elric     close SP;
    151  1.1  elric }
    152  1.1  elric 
    153  1.1  elric sub process_file($)
    154  1.1  elric {
    155  1.1  elric     $fn = shift;
    156  1.1  elric 
    157  1.1  elric     if ($fn =~ m/\.dll$/i) {
    158  1.1  elric 	build_def_file($fn);
    159  1.1  elric     } elsif ($fn =~ m/\.obj$/i) {
    160  1.1  elric 	build_local_exports_list($fn);
    161  1.1  elric     } else {
    162  1.1  elric 	die "File type not recognized for $fn.";
    163  1.1  elric     }
    164  1.1  elric }
    165  1.1  elric 
    166  1.1  elric sub use_response_file($)
    167  1.1  elric {
    168  1.1  elric     $fn = shift;
    169  1.1  elric 
    170  1.1  elric     open (RF, '<', $fn) or die "Can't open response file $fn";
    171  1.1  elric 
    172  1.1  elric     while (<RF>) {
    173  1.1  elric 	/^(\S+)$/ && do {
    174  1.1  elric 	    process_file($1);
    175  1.1  elric 	}
    176  1.1  elric     }
    177  1.1  elric     close RF;
    178  1.1  elric }
    179  1.1  elric 
    180  1.1  elric print "; This is a generated file.  Do not modify directly.\n";
    181  1.1  elric print "EXPORTS\n";
    182  1.1  elric 
    183  1.1  elric for (@ARGV) {
    184  1.1  elric     ARG: {
    185  1.1  elric 	/^-m(.*)$/ && do {
    186  1.1  elric 	    $module_name = $1.".";
    187  1.1  elric 	    last ARG;
    188  1.1  elric 	};
    189  1.1  elric 
    190  1.1  elric         /^-l(.*)$/ && do {
    191  1.1  elric             $local_prefix = $1."_";
    192  1.1  elric             last ARG;
    193  1.1  elric         };
    194  1.1  elric 
    195  1.1  elric         /^-a$/ && do {
    196  1.1  elric             $always_export = 1;
    197  1.1  elric             last ARG;
    198  1.1  elric         };
    199  1.1  elric 
    200  1.1  elric 	/^-e(.*)$/ && do {
    201  1.1  elric 	    build_forwarder_target_list($1);
    202  1.1  elric 	    last ARG;
    203  1.1  elric 	};
    204  1.1  elric 
    205  1.1  elric 	/^@(.*)$/ && do {
    206  1.1  elric 	    use_response_file($1);
    207  1.1  elric 	    last ARG;
    208  1.1  elric 	};
    209  1.1  elric 
    210  1.1  elric 	process_file($_);
    211  1.1  elric     }
    212  1.1  elric }
    213