This is the mail archive of the mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Importlib converter

Maybe this is useful for someone else. It's a small Perl script that 
can convert short-format import libraries (a number of which can be 
found in the MSDN stuff, for example) into .def files, and then calls 
dlltool on those.

And maybe someone can put this functionality into dlltool and/or 
expand it to understand long format.

Regards - Kai Henningsen

Spuentrup CTI       Fon: +49 700 CALL CATS (=22 55 22 87)
Windbreede 12       Fax: +49 251 322311 99
D-48157 Muenster    Mob: +49 161 322311 1
Germany             GSM: +49 171 7755060

#! E:\Perl\bin\perl.exe -w

use strict;

#use Data::Dumper;
#$Data::Dumper::Useqq = 1;

my %defs;

$| = 1;

for my $lib (@ARGV) {
	print "\n* $lib\n";
	if (! open LIB, "< $lib") {
		print "$lib: $!\n";
	binmode LIB;
	$/ = undef;
	my $libdata = <LIB>;
	close LIB;
	if ($libdata !~ m/!<arch>\n/) {
		print "$lib: bad magic\n";
	$libdata = substr $libdata, 8;
	while (length $libdata) {
		my @hdr = unpack "A16 A12 A6 A6 A8 A10 A2 a*", $libdata;
		my $size = $hdr[5];
		my $member;
		my $odd = $size & 1;
		my $filler;
		($member, $filler, $libdata) = unpack "a$size a$odd a*", pop @hdr;
		#print "Header = '", join("' '", @hdr), "'\n";
		next if $hdr[0] eq '/' or $hdr[0] eq '//';
		# try for short format
		my @member = unpack "vvvvVVvva*", $member;
		my $s = pop @member;
		my $zeroes = ($s =~ tr/\0//);
		push @member, split m/\0/s, $s if $zeroes < 4;
		#print Data::Dumper->Dump([$member, \@member], [qw'$member @member']);
		if (@member == 10 && $member[0]==0 && $member[1]==65535) {
			#printf "s=%04x %04x v=%04x m=%04x d=%08x l=%08x h=%04x f=%04x s=%s d=%s\n", @member;
			print ".";
			my $dll = lc $member[9];
			$dll =~ s/\.dll$//;
			$defs{$dll} = [$member[9]] unless exists $defs{$dll};
			my $sym = $member[8];
			$sym =~ s/^_//;
			push @{$defs{$dll}}, $sym;
		else {
			printf "Long format member %s (%d bytes, ignored)\n", $hdr[0], length $member;
			#my @s = split //, $member;
            #printf +("%02x " x @s) . "\n", map ord, @s;
	print "\n";
print "\n";
while (my ($dll, $defs) = each %defs) {
	my $dllname = shift @$defs;
	print "-> $dllname\n";
	my $defname = "$dll.def";
	open DEF, "> $defname" or die "$defname: $!";
	print DEF "EXPORTS\n", join("\n", @$defs), "\n";
	close DEF;
	system('dlltool', '--def', $defname, '--dllname', $dllname, '--output-lib', "lib$dll.a");

Want to unsubscribe from this list?
Send a message to

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]