1*c2e0c6b5SAndroid Build Coastguard Worker#!/usr/bin/perl 2*c2e0c6b5SAndroid Build Coastguard Workeruse strict; 3*c2e0c6b5SAndroid Build Coastguard Workeruse warnings; 4*c2e0c6b5SAndroid Build Coastguard Workerdie "Usage: $0 script.ver dllname build.def import.def\n" if @ARGV != 4; 5*c2e0c6b5SAndroid Build Coastguard Workermy ($verfile, $dllname, $builddef, $importdef) = @ARGV; 6*c2e0c6b5SAndroid Build Coastguard Workeropen my $verfh, '<', $verfile or die "Cannot open input file $verfile: $!\n"; 7*c2e0c6b5SAndroid Build Coastguard Workermy $input = join '', <$verfh>; 8*c2e0c6b5SAndroid Build Coastguard Workerclose $verfh; 9*c2e0c6b5SAndroid Build Coastguard Workermy @syms; 10*c2e0c6b5SAndroid Build Coastguard Workermy (%cnt, %last, %ords); 11*c2e0c6b5SAndroid Build Coastguard Worker$input =~ s/\/\*.*?\*\///sg; # Remove C comments 12*c2e0c6b5SAndroid Build Coastguard Workerwhile ($input =~ m/(\S+)\s*\{((?:[^\{\}]|\{(?2)\})+)\}\s*;/sg) { # Split {...} 13*c2e0c6b5SAndroid Build Coastguard Worker my ($ver, $block) = ($1, $2); 14*c2e0c6b5SAndroid Build Coastguard Worker while ($block =~ s/(\S+)\s*:((?:[^\{\}:]|\{(?2)\})+)$//sg) { # Split section: 15*c2e0c6b5SAndroid Build Coastguard Worker my ($section, $syms) = ($1, $2); 16*c2e0c6b5SAndroid Build Coastguard Worker next if $section ne 'global'; 17*c2e0c6b5SAndroid Build Coastguard Worker $syms =~ s/\s+//g; 18*c2e0c6b5SAndroid Build Coastguard Worker foreach (split /;\s*/, $syms) { # Split symbols 19*c2e0c6b5SAndroid Build Coastguard Worker $cnt{$_}++; 20*c2e0c6b5SAndroid Build Coastguard Worker $last{$_} = $ver; 21*c2e0c6b5SAndroid Build Coastguard Worker push @syms, [$_, $ver]; 22*c2e0c6b5SAndroid Build Coastguard Worker } 23*c2e0c6b5SAndroid Build Coastguard Worker } 24*c2e0c6b5SAndroid Build Coastguard Worker} 25*c2e0c6b5SAndroid Build Coastguard Workeropen my $importfh, '>', $importdef or die "Cannot open output file $importdef: $!\n"; 26*c2e0c6b5SAndroid Build Coastguard Workeropen my $buildfh, '>', $builddef or die "Cannot open output file $builddef: $!\n"; 27*c2e0c6b5SAndroid Build Coastguard Workerprint $importfh "LIBRARY \"$dllname\"\n"; 28*c2e0c6b5SAndroid Build Coastguard Workerprint $importfh "EXPORTS\n"; 29*c2e0c6b5SAndroid Build Coastguard Workerprint $buildfh "EXPORTS\n"; 30*c2e0c6b5SAndroid Build Coastguard Workermy $ord = 1; 31*c2e0c6b5SAndroid Build Coastguard Workerforeach (@syms) { 32*c2e0c6b5SAndroid Build Coastguard Worker my ($sym, $ver) = @{$_}; 33*c2e0c6b5SAndroid Build Coastguard Worker print $importfh "\"$sym\@$ver\" \@$ord\n"; 34*c2e0c6b5SAndroid Build Coastguard Worker if ($last{$sym} ne $ver) { 35*c2e0c6b5SAndroid Build Coastguard Worker print $buildfh "\"$sym\@$ver\" \@$ord\n"; 36*c2e0c6b5SAndroid Build Coastguard Worker } else { 37*c2e0c6b5SAndroid Build Coastguard Worker $ords{$sym} = $ord; 38*c2e0c6b5SAndroid Build Coastguard Worker print $buildfh "\"$sym\@$ver\" = " . (($cnt{$sym} > 1) ? "\"$sym\@\@$ver\"" : $sym) . " \@$ord\n" 39*c2e0c6b5SAndroid Build Coastguard Worker } 40*c2e0c6b5SAndroid Build Coastguard Worker $ord++; 41*c2e0c6b5SAndroid Build Coastguard Worker} 42*c2e0c6b5SAndroid Build Coastguard Worker# GNU dlltool has broken calculation of ordinals for aliased symbols, so specify ordinals explicitly 43*c2e0c6b5SAndroid Build Coastguard Worker# GNU LD prior 2.21 has broken handling of symbols with dot character 44*c2e0c6b5SAndroid Build Coastguard Worker# Operator == for defining symbol alias is supported since GNU dlltool 2.21 45*c2e0c6b5SAndroid Build Coastguard Workerprint $importfh "$_ \@$ords{$_} == \"$_\@$last{$_}\"\n" foreach sort keys %last; 46*c2e0c6b5SAndroid Build Coastguard Workerclose $importfh; 47*c2e0c6b5SAndroid Build Coastguard Workerclose $buildfh; 48