summaryrefslogtreecommitdiffstats
path: root/lib/ver2def.pl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:24:33 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:24:33 +0000
commit7a19c99f661602b67db95fd1d8aca5fe3a387441 (patch)
tree215ff04ec522779fa83acf394d296c2356c6b382 /lib/ver2def.pl
parentInitial commit. (diff)
downloadpciutils-upstream/1%3.9.0.tar.xz
pciutils-upstream/1%3.9.0.zip
Adding upstream version 1:3.9.0.upstream/1%3.9.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/ver2def.pl')
-rwxr-xr-xlib/ver2def.pl47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/ver2def.pl b/lib/ver2def.pl
new file mode 100755
index 0000000..18231bc
--- /dev/null
+++ b/lib/ver2def.pl
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+die "Usage: $0 script.ver dllname build.def import.def\n" if @ARGV != 4;
+my ($verfile, $dllname, $builddef, $importdef) = @ARGV;
+open my $verfh, '<', $verfile or die "Cannot open input file $verfile: $!\n";
+my $input = join '', <$verfh>;
+close $verfh;
+my @syms;
+my (%cnt, %last, %ords);
+$input =~ s/\/\*.*?\*\///sg; # Remove C comments
+while ($input =~ m/(\S+)\s*\{((?:[^\{\}]|\{(?2)\})+)\}\s*;/sg) { # Split {...}
+ my ($ver, $block) = ($1, $2);
+ while ($block =~ s/(\S+)\s*:((?:[^\{\}:]|\{(?2)\})+)$//sg) { # Split section:
+ my ($section, $syms) = ($1, $2);
+ next if $section ne 'global';
+ $syms =~ s/\s+//g;
+ foreach (split /;\s*/, $syms) { # Split symbols
+ $cnt{$_}++;
+ $last{$_} = $ver;
+ push @syms, [$_, $ver];
+ }
+ }
+}
+open my $importfh, '>', $importdef or die "Cannot open output file $importdef: $!\n";
+open my $buildfh, '>', $builddef or die "Cannot open output file $builddef: $!\n";
+print $importfh "LIBRARY \"$dllname\"\n";
+print $importfh "EXPORTS\n";
+print $buildfh "EXPORTS\n";
+my $ord = 1;
+foreach (@syms) {
+ my ($sym, $ver) = @{$_};
+ print $importfh "\"$sym\@$ver\" \@$ord\n";
+ if ($last{$sym} ne $ver) {
+ print $buildfh "\"$sym\@$ver\" \@$ord\n";
+ } else {
+ $ords{$sym} = $ord;
+ print $buildfh "\"$sym\@$ver\" = " . (($cnt{$sym} > 1) ? "\"$sym\@\@$ver\"" : $sym) . " \@$ord\n"
+ }
+ $ord++;
+}
+# GNU dlltool has broken calculation of ordinals for aliased symbols, so specify ordinals explicitly
+# GNU LD prior 2.21 has broken handling of symbols with dot character
+# Operator == for defining symbol alias is supported since GNU dlltool 2.21
+print $importfh "$_ \@$ords{$_} == \"$_\@$last{$_}\"\n" foreach sort keys %last;
+close $importfh;
+close $buildfh;