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