Commit 49c7681c58dd6dbd85afcdb9884a5dc8ed766192

Authored by Jay Berkenbilt
1 parent 3803e9cc

Windows install: check DLL type

When copying dlls, make sure to only consider DLLs whose type matches
the type of what is loading them.
Showing 3 changed files with 46 additions and 9 deletions
ChangeLog
  1 +2013-03-11 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * When creating Windows binary distributions, make sure to only
  4 + copy DLLs of the correct type. The ensures that the 32-bit
  5 + distributions contain 32-bit DLLs and the 64-bit distributions
  6 + contain 64-bit DLLs.
  7 +
1 2013-03-07 Jay Berkenbilt <ejb@ql.org> 8 2013-03-07 Jay Berkenbilt <ejb@ql.org>
2 9
3 * Use ./install-sh (already present) instead of "install -c" to 10 * Use ./install-sh (already present) instead of "install -c" to
@@ -22,12 +22,6 @@ @@ -22,12 +22,6 @@
22 22
23 - See ../misc/broken-files 23 - See ../misc/broken-files
24 24
25 - * The mingw64 package is broken. It contains a 32-bit version of  
26 - libstdc++-6.dll. Fix this and make sure it can never happen  
27 - again. Ideally we should test in a sandbox, but failing that, at  
28 - least run file on all the dlls to make sure they are of the right  
29 - type.  
30 -  
31 * Add to documentation, and mention this documentation in 25 * Add to documentation, and mention this documentation in
32 README.maintainer: 26 README.maintainer:
33 27
copy_dlls
@@ -12,6 +12,7 @@ my ($file, $destdir, $objdump) = @ARGV; @@ -12,6 +12,7 @@ my ($file, $destdir, $objdump) = @ARGV;
12 my $filedir = dirname($file); 12 my $filedir = dirname($file);
13 13
14 my %dlls = (); 14 my %dlls = ();
  15 +my $format = undef;
15 open(O, "$objdump -p $file|") or die "$whoami: can't run objdump\n"; 16 open(O, "$objdump -p $file|") or die "$whoami: can't run objdump\n";
16 while (<O>) 17 while (<O>)
17 { 18 {
@@ -22,11 +23,21 @@ while (&lt;O&gt;) @@ -22,11 +23,21 @@ while (&lt;O&gt;)
22 next if $dll =~ m/^(kernel32|user32|msvcrt)\.dll$/; 23 next if $dll =~ m/^(kernel32|user32|msvcrt)\.dll$/;
23 $dlls{$dll} = 1; 24 $dlls{$dll} = 1;
24 } 25 }
  26 + elsif (m/^Magic.*\((PE.+?)\)/)
  27 + {
  28 + $format = $1;
  29 + }
25 } 30 }
26 close(O); 31 close(O);
  32 +if (! defined $format)
  33 +{
  34 + die "$whoami: can't determine format of $file\n";
  35 +}
27 36
28 -# Search the file's directory, the current directory, and the path for  
29 -# dlls since that's what Windows does. 37 +# Search the directories named in the file's manifest (if present),
  38 +# the file's directory, the current directory, and the path for dlls
  39 +# since that's what Windows does. Be sure to only capture compatible
  40 +# DLLs.
30 my $sep = ($^O eq 'MSWin32' ? ';' : ':'); 41 my $sep = ($^O eq 'MSWin32' ? ';' : ':');
31 my @path = ($filedir, '.', split($sep, $ENV{'PATH'})); 42 my @path = ($filedir, '.', split($sep, $ENV{'PATH'}));
32 if (-f "$file.manifest") 43 if (-f "$file.manifest")
@@ -41,7 +52,7 @@ foreach my $dll (sort keys %dlls) @@ -41,7 +52,7 @@ foreach my $dll (sort keys %dlls)
41 my $found = 0; 52 my $found = 0;
42 foreach my $dir (@path) 53 foreach my $dir (@path)
43 { 54 {
44 - if (-f "$dir/$dll") 55 + if ((-f "$dir/$dll") && is_format("$dir/$dll", $format))
45 { 56 {
46 push(@final, "$dir/$dll"); 57 push(@final, "$dir/$dll");
47 $found = 1; 58 $found = 1;
@@ -68,6 +79,31 @@ foreach my $f (@final) @@ -68,6 +79,31 @@ foreach my $f (@final)
68 die "$whoami: copy $f to $destdir failed\n"; 79 die "$whoami: copy $f to $destdir failed\n";
69 } 80 }
70 81
  82 +sub is_format
  83 +{
  84 + my ($file, $format) = @_;
  85 + $file =~ s,\\,/,g;
  86 + # Special case: msvc*.dll seem to be able to behave both as 32-bit
  87 + # and 64-bit DLLs. Either that, or this logic is wrong for those
  88 + # DLLs and it doesn't matter because they're already installed on
  89 + # my test system (which doesn't have msvc installed on it).
  90 + if ($file =~ m,/msvc,i)
  91 + {
  92 + return 1;
  93 + }
  94 + my $result = 0;
  95 + my $file_format = `file $file`;
  96 + print "$file $format $file_format\n";
  97 + if ($? == 0)
  98 + {
  99 + if ($file_format =~ m/\Q${format}\E executable/)
  100 + {
  101 + $result = 1;
  102 + }
  103 + }
  104 + $result;
  105 +}
  106 +
71 sub get_manifest_dirs 107 sub get_manifest_dirs
72 { 108 {
73 # Find all system directories in which to search for DLLs based on 109 # Find all system directories in which to search for DLLs based on