nasm/nsis/getpearch.pl
H. Peter Anvin d4c67b1597 nsis: make nsis output automatically select architecture
Make the NSIS output automatically select the output architecture to
generate the proper filename and, much more importantly, set up the
proper default install directory.

This requires Perl as well as makensis to be present in order to make
an installer, but that doesn't really seem like a too onerous of a
requirement (NSIS being the big external dependency here.)

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2016-03-03 21:37:37 -08:00

74 lines
1.7 KiB
Perl

#!/usr/bin/perl
#
# Get the appropriate variables to make an NSIS installer file
# based on the PE architecture of a specific file
#
use strict;
my %archnames = (
0x01de => 'am33',
0x8664 => 'x64',
0x01c0 => 'arm32',
0x01c4 => 'thumb',
0xaa64 => 'arm64',
0x0ebc => 'efi',
0x014c => 'x86',
0x0200 => 'ia64',
0x9041 => 'm32r',
0x0266 => 'mips16',
0x0366 => 'mips',
0x0466 => 'mips16',
0x01f0 => 'powerpc',
0x01f1 => 'powerpc',
0x0166 => 'mips',
0x01a2 => 'sh3',
0x01a3 => 'sh3',
0x01a6 => 'sh4',
0x01a8 => 'sh5',
0x01c2 => 'arm32',
0x0169 => 'wcemipsv2'
);
my ($file) = @ARGV;
open(my $fh, '<', $file)
or die "$0: cannot open file: $file: $!\n";
read($fh, my $mz, 2);
exit 0 if ($mz ne 'MZ');
exit 0 unless (seek($fh, 0x3c, 0));
exit 0 unless (read($fh, my $pe_offset, 1) == 1);
$pe_offset = unpack("C", $pe_offset);
exit 0 unless (seek($fh, $pe_offset, 0));
read($fh, my $pe, 4);
exit 0 unless ($pe eq "PE\0\0");
exit 0 unless (read($fh, my $arch, 2) == 2);
$arch = $archnames{unpack("v", $arch)};
if (defined($arch)) {
print "!define ARCH ${arch}\n";
}
exit 0 unless (seek($fh, 14, 1));
exit 0 unless (read($fh, my $auxheaderlen, 2) == 2);
exit 0 unless (unpack("v", $auxheaderlen) >= 2);
exit 0 unless (seek($fh, 2, 1));
exit 0 unless (read($fh, my $petype, 2) == 2);
$petype = unpack("v", $petype);
if ($petype == 0x010b) {
# It is a 32-bit PE32 file
print "!define BITS 32\n";
print "!define GLOBALINSTDIR \$PROGRAMFILES\n";
} elsif ($petype == 0x020b) {
# It is a 64-bit PE32+ file
print "!define BITS 64\n";
print "!define GLOBALINSTDIR \$PROGRAMFILES64\n";
} else {
# No idea...
}
close($fh);
exit 0;