aboutsummaryrefslogtreecommitdiffstats
path: root/gpxe/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'gpxe/src/util')
-rw-r--r--gpxe/src/util/.gitignore1
-rwxr-xr-xgpxe/src/util/diffsize.pl101
-rwxr-xr-xgpxe/src/util/dskpad.pl12
-rw-r--r--gpxe/src/util/elf2efi.c7
-rwxr-xr-xgpxe/src/util/geniso5
-rwxr-xr-xgpxe/src/util/genliso51
-rwxr-xr-xgpxe/src/util/gensdsk65
-rw-r--r--gpxe/src/util/iccfix.c156
-rwxr-xr-xgpxe/src/util/licence.pl149
-rwxr-xr-xgpxe/src/util/makerom.pl30
-rwxr-xr-xgpxe/src/util/modrom.pl4
-rwxr-xr-xgpxe/src/util/padimg.pl44
-rw-r--r--gpxe/src/util/parserom.pl3
-rw-r--r--gpxe/src/util/zbin.c144
14 files changed, 653 insertions, 119 deletions
diff --git a/gpxe/src/util/.gitignore b/gpxe/src/util/.gitignore
index c2567012..a3752470 100644
--- a/gpxe/src/util/.gitignore
+++ b/gpxe/src/util/.gitignore
@@ -5,3 +5,4 @@ prototester
elf2efi32
elf2efi64
efirom
+iccfix
diff --git a/gpxe/src/util/diffsize.pl b/gpxe/src/util/diffsize.pl
new file mode 100755
index 00000000..d4978c2a
--- /dev/null
+++ b/gpxe/src/util/diffsize.pl
@@ -0,0 +1,101 @@
+#!/usr/bin/perl -w
+# usage:
+# [somebody@somewhere ~/gpxe/src]$ ./util/diffsize.pl [<old rev> [<new rev>]]
+# by default <old rev> is HEAD and <new rev> is the working tree
+
+use strict;
+
+-d "bin" or die "Please run me in the gPXE src directory\n";
+mkdir ".sizes";
+
+my($oldrev, $newrev);
+my($oldname, $newname);
+
+if (@ARGV) {
+ $oldname = shift;
+} else {
+ $oldname = "HEAD";
+}
+
+if (@ARGV) {
+ $newname = shift;
+} else {
+ $newrev = "tree" . time();
+}
+
+$oldrev = `git rev-parse $oldname`;
+chomp $oldrev;
+
+unless (defined $newrev) {
+ $newrev = `git rev-parse $newname`;
+ chomp $newrev;
+}
+
+sub calc_sizes($$) {
+ my($name, $rev) = @_;
+ my $output;
+ my $lastrev;
+ my $stashed = 0;
+ my $res = 0;
+
+ return if -e ".sizes/$rev.sizes";
+
+ if (defined $name) {
+ $output = `git stash`;
+ $stashed = 1 unless $output =~ /No local changes to save/;
+ $lastrev = `git name-rev --name-only HEAD`;
+ system("git checkout $name >/dev/null"); $res ||= $?;
+ }
+
+ system("make -j4 bin/gpxe.lkrn >/dev/null"); $res ||= $?;
+ system("make bin/gpxe.lkrn.sizes > .sizes/$rev.sizes"); $res ||= $?;
+
+ if (defined $name) {
+ system("git checkout $lastrev >/dev/null"); $res ||= $?;
+ system("git stash pop >/dev/null") if $stashed; $res ||= $?;
+ }
+
+ if ($res) {
+ unlink(".sizes/$rev.sizes");
+ die "Error making sizes file\n";
+ }
+}
+
+our %Sizes;
+
+sub save_sizes($$) {
+ my($id, $rev) = @_;
+ my $file = ".sizes/$rev.sizes";
+
+ open SIZES, $file or die "opening $file: $!\n";
+ while (<SIZES>) {
+ my($text, $data, $bss, $total, $hex, $name) = split;
+ $name =~ s|bin/||; $name =~ s|\.o$||;
+
+ # Skip the header and totals lines
+ next if $total =~ /[a-z]/ or $name =~ /TOTALS/;
+
+ # Skip files named with dash, due to old Makefile bug
+ next if $name =~ /-/;
+
+ $Sizes{$name} = {old => 0, new => 0} unless exists $Sizes{$name};
+ $Sizes{$name}{$id} = $total;
+ }
+}
+
+calc_sizes($oldname, $oldrev);
+calc_sizes($newname, $newrev);
+
+save_sizes('old', $oldrev);
+save_sizes('new', $newrev);
+
+my $total = 0;
+
+for (sort keys %Sizes) {
+ my $diff = $Sizes{$_}{new} - $Sizes{$_}{old};
+ if (abs($diff) >= 16) {
+ printf "%12s %+d\n", substr($_, 0, 12), $Sizes{$_}{new} - $Sizes{$_}{old};
+ }
+ $total += $diff;
+}
+printf " TOTAL: %+d\n", $total;
diff --git a/gpxe/src/util/dskpad.pl b/gpxe/src/util/dskpad.pl
deleted file mode 100755
index 3ae325eb..00000000
--- a/gpxe/src/util/dskpad.pl
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-use warnings;
-
-use constant FLOPPYSIZE => 1440 * 1024;
-
-while ( my $filename = shift ) {
- die "$filename is not a file\n" unless -f $filename;
- die "$filename is too large\n" unless ( -s $filename <= FLOPPYSIZE );
- truncate $filename, FLOPPYSIZE or die "Could not truncate: $!\n";
-}
diff --git a/gpxe/src/util/elf2efi.c b/gpxe/src/util/elf2efi.c
index 886777d9..bb766bd3 100644
--- a/gpxe/src/util/elf2efi.c
+++ b/gpxe/src/util/elf2efi.c
@@ -29,6 +29,7 @@
#include <bfd.h>
#include <gpxe/efi/efi.h>
#include <gpxe/efi/IndustryStandard/PeImage.h>
+#include <libgen.h>
#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
@@ -658,6 +659,7 @@ static void write_pe_file ( struct pe_header *pe_header,
*/
static void elf2pe ( const char *elf_name, const char *pe_name,
struct options *opts ) {
+ char pe_name_tmp[ strlen ( pe_name ) + 1 ];
bfd *bfd;
asymbol **symtab;
asection *section;
@@ -669,6 +671,9 @@ static void elf2pe ( const char *elf_name, const char *pe_name,
struct pe_header pe_header;
FILE *pe;
+ /* Create a modifiable copy of the PE name */
+ memcpy ( pe_name_tmp, pe_name, sizeof ( pe_name_tmp ) );
+
/* Open the file */
bfd = open_input_bfd ( elf_name );
symtab = read_symtab ( bfd );
@@ -703,7 +708,7 @@ static void elf2pe ( const char *elf_name, const char *pe_name,
/* Create the .reloc section */
*(next_pe_section) = create_debug_section ( &pe_header,
- basename ( pe_name ) );
+ basename ( pe_name_tmp ) );
next_pe_section = &(*next_pe_section)->next;
/* Write out PE file */
diff --git a/gpxe/src/util/geniso b/gpxe/src/util/geniso
index d7ddbd2b..7c2f7672 100755
--- a/gpxe/src/util/geniso
+++ b/gpxe/src/util/geniso
@@ -17,13 +17,12 @@ esac
isolinux_bin=${ISOLINUX_BIN:-util/isolinux.bin}
if [ ! -r $isolinux_bin ]
then
- echo $0: $isolinux_bin not found, please install, or set ISOLINUX_BIN in arch/i386/config correctly
+ echo $0: $isolinux_bin not found, please install, or set ISOLINUX_BIN in arch/i386/Makefile correctly
exit 1
fi
out=$1
shift
-dir=bin/iso.dir
-mkdir -p $dir
+dir=`mktemp -d bin/iso.dir.XXXXXX`
cfg=$dir/isolinux.cfg
cp -p $isolinux_bin $dir
cat > $cfg <<EOF
diff --git a/gpxe/src/util/genliso b/gpxe/src/util/genliso
index 0a67eb3c..1f1c1168 100755
--- a/gpxe/src/util/genliso
+++ b/gpxe/src/util/genliso
@@ -2,51 +2,42 @@
#
# Generate a legacy floppy emulation ISO boot image
#
-# genliso foo.liso foo.lkrn
+# genliso foo.liso foo.lkrn bar.lkrn ...
#
-# the ISO image is the first argument so that a list of .lkrn images
-# to include can be specified
-#
-case $0 in
-*genliso)
- ;;
-*genfdimg)
- genfdimg=1
- ;;
-esac
+# The .liso image filename is the first argument followed by
+# a list of .lkrn images include in .liso image
+
case $# in
0|1)
echo Usage: $0 foo.liso foo.lkrn ...
exit 1
;;
esac
+
case "`mtools -V`" in
-Mtools\ version\ 3.9.9*|Mtools\ version\ 3.9.1[0-9]*|Mtools\ version\ 4.*)
+Mtools\ version\ 3.9.9*|Mtools\ version\ 3.9.1[0-9]*|[mM]tools\ *\ [4-9].*)
;;
*)
echo Mtools version 3.9.9 or later is required
exit 1
;;
esac
+
out=$1
shift
-dir=bin/liso.dir
-mkdir -p $dir
-case "$genfdimg" in
-1)
- img=$out
- ;;
-*)
- img=$dir/boot.img
- ;;
-esac
+
+dir=`mktemp -d bin/liso.dir.XXXXXX`
+
+img=$dir/boot.img
mformat -f 1440 -C -i $img ::
-cfg=bin/syslinux.cfg
+
+cfg=$dir/syslinux.cfg
cat > $cfg <<EOF
# These default options can be changed in the genliso script
-SAY Etherboot ISO boot image generated by genliso
+SAY gPXE ISO boot image generated by genliso
TIMEOUT 30
EOF
+
first=
for f
do
@@ -70,16 +61,14 @@ do
echo "" KERNEL $g
mcopy -m -i $img $f ::$g
done >> $cfg
+
mcopy -i $img $cfg ::syslinux.cfg
+
if ! syslinux $img
then
exit 1
fi
-case "$genfdimg" in
-1)
- ;;
-*)
- mkisofs -o $out -c boot.cat -b boot.img $dir
- ;;
-esac
+
+mkisofs -q -o $out -c boot.cat -b boot.img $dir
+
rm -fr $dir
diff --git a/gpxe/src/util/gensdsk b/gpxe/src/util/gensdsk
new file mode 100755
index 00000000..a8661586
--- /dev/null
+++ b/gpxe/src/util/gensdsk
@@ -0,0 +1,65 @@
+#!/bin/bash
+#
+# Generate a syslinux floppy that loads a gPXE image
+#
+# gensdsk foo.sdsk foo.lkrn
+#
+# the floppy image is the first argument
+# followed by list of .lkrn images
+#
+
+case $# in
+0|1)
+ echo Usage: $0 foo.sdsk foo.lkrn ...
+ exit 1
+ ;;
+esac
+case "`mtools -V`" in
+Mtools\ version\ 3.9.9*|Mtools\ version\ 3.9.1[0-9]*|[mM]tools\ *\ [4-9].*)
+ ;;
+*)
+ echo Mtools version 3.9.9 or later is required
+ exit 1
+ ;;
+esac
+img=$1
+shift
+dir=`mktemp -d bin/sdsk.dir.XXXXXX`
+
+mformat -f 1440 -C -i $img ::
+cfg=$dir/syslinux.cfg
+cat > $cfg <<EOF
+
+# These default options can be changed in the gensdsk script
+TIMEOUT 30
+EOF
+first=
+for f
+do
+ if [ ! -r $f ]
+ then
+ echo $f does not exist, skipping 1>&2
+ continue
+ fi
+ # shorten name for 8.3 filesystem
+ b=$(basename $f)
+ g=${b%.lkrn}
+ g=${g//[^a-z0-9]}
+ g=${g:0:8}.krn
+ case "$first" in
+ "")
+ echo DEFAULT $g
+ ;;
+ esac
+ first=$g
+ echo LABEL $b
+ echo "" KERNEL $g
+ mcopy -m -i $img $f ::$g
+done >> $cfg
+mcopy -i $img $cfg ::syslinux.cfg
+if ! syslinux $img
+then
+ exit 1
+fi
+
+rm -fr $dir
diff --git a/gpxe/src/util/iccfix.c b/gpxe/src/util/iccfix.c
new file mode 100644
index 00000000..303ae9ca
--- /dev/null
+++ b/gpxe/src/util/iccfix.c
@@ -0,0 +1,156 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <elf.h>
+#include <gpxe/tables.h>
+
+#define DEBUG 0
+
+#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
+
+#define dprintf(...) do { \
+ if ( DEBUG ) \
+ fprintf ( stderr, __VA_ARGS__ ); \
+ } while ( 0 )
+
+#ifdef SELF_INCLUDED
+
+/**
+ * Fix up ICC alignments
+ *
+ * @v elf ELF header
+ * @ret rc Return status code
+ *
+ * See comments in tables.h for an explanation of why this monstrosity
+ * is necessary.
+ */
+static int ICCFIX ( void *elf ) {
+ ELF_EHDR *ehdr = elf;
+ ELF_SHDR *shdr = ( elf + ehdr->e_shoff );
+ size_t shentsize = ehdr->e_shentsize;
+ unsigned int shnum = ehdr->e_shnum;
+ ELF_SHDR *strtab = ( ( ( void * ) shdr ) +
+ ( ehdr->e_shstrndx * shentsize ) );
+ char *strings = ( elf + strtab->sh_offset );
+
+ for ( ; shnum-- ; shdr = ( ( ( void * ) shdr ) + shentsize ) ) {
+ char *name = ( strings + shdr->sh_name );
+ unsigned long align = shdr->sh_addralign;
+ unsigned long new_align;
+
+ if ( ( strncmp ( name, ".tbl.", 5 ) == 0 ) &&
+ ( align >= ICC_ALIGN_HACK_FACTOR ) ) {
+ new_align = ( align / ICC_ALIGN_HACK_FACTOR );
+ shdr->sh_addralign = new_align;
+ dprintf ( "Section \"%s\": alignment %d->%d\n",
+ name, align, new_align );
+ }
+ }
+ return 0;
+}
+
+#else /* SELF_INCLUDED */
+
+#define SELF_INCLUDED
+
+/* Include iccfix32() function */
+#define ELF_EHDR Elf32_Ehdr
+#define ELF_SHDR Elf32_Shdr
+#define ICCFIX iccfix32
+#include "iccfix.c"
+#undef ELF_EHDR
+#undef ELF_SHDR
+#undef ICCFIX
+
+/* Include iccfix64() function */
+#define ELF_EHDR Elf64_Ehdr
+#define ELF_SHDR Elf64_Shdr
+#define ICCFIX iccfix64
+#include "iccfix.c"
+#undef ELF_EHDR
+#undef ELF_SHDR
+#undef ICCFIX
+
+static int iccfix ( const char *filename ) {
+ int fd;
+ struct stat stat;
+ void *elf;
+ unsigned char *eident;
+ int rc;
+
+ /* Open and mmap file */
+ fd = open ( filename, O_RDWR );
+ if ( fd < 0 ) {
+ eprintf ( "Could not open %s: %s\n",
+ filename, strerror ( errno ) );
+ rc = -1;
+ goto err_open;
+ }
+ if ( fstat ( fd, &stat ) < 0 ) {
+ eprintf ( "Could not determine size of %s: %s\n",
+ filename, strerror ( errno ) );
+ rc = -1;
+ goto err_fstat;
+ }
+ elf = mmap ( NULL, stat.st_size, ( PROT_READ | PROT_WRITE ),
+ MAP_SHARED, fd, 0 );
+ if ( elf == MAP_FAILED ) {
+ eprintf ( "Could not map %s: %s\n",
+ filename, strerror ( errno ) );
+ rc = -1;
+ goto err_mmap;
+ }
+
+ /* Perform fixups */
+ eident = elf;
+ switch ( eident[EI_CLASS] ) {
+ case ELFCLASS32:
+ rc = iccfix32 ( elf );
+ break;
+ case ELFCLASS64:
+ rc = iccfix64 ( elf );
+ break;
+ default:
+ eprintf ( "Unknown ELF class %d in %s\n",
+ eident[EI_CLASS], filename );
+ rc = -1;
+ break;
+ }
+
+ munmap ( elf, stat.st_size );
+ err_mmap:
+ err_fstat:
+ close ( fd );
+ err_open:
+ return rc;
+}
+
+int main ( int argc, char **argv ) {
+ int i;
+ int rc;
+
+ /* Parse command line */
+ if ( argc < 2 ) {
+ eprintf ( "Syntax: %s <object_file>...\n", argv[0] );
+ exit ( 1 );
+ }
+
+ /* Process each object in turn */
+ for ( i = 1 ; i < argc ; i++ ) {
+ if ( ( rc = iccfix ( argv[i] ) ) != 0 ) {
+ eprintf ( "Could not fix up %s\n", argv[i] );
+ exit ( 1 );
+ }
+ }
+
+ return 0;
+}
+
+#endif /* SELF_INCLUDED */
diff --git a/gpxe/src/util/licence.pl b/gpxe/src/util/licence.pl
new file mode 100755
index 00000000..c37685d3
--- /dev/null
+++ b/gpxe/src/util/licence.pl
@@ -0,0 +1,149 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+# List of licences we can handle
+my $known_licences = {
+ gpl_any => {
+ desc => "GPL (any version)",
+ can_subsume => {
+ public_domain => 1,
+ bsd3 => 1,
+ bsd2 => 1,
+ mit => 1,
+ isc => 1,
+ },
+ },
+ gpl2_or_later => {
+ desc => "GPL version 2 (or, at your option, any later version)",
+ can_subsume => {
+ gpl_any => 1,
+ public_domain => 1,
+ bsd3 => 1,
+ bsd2 => 1,
+ mit => 1,
+ isc => 1,
+ },
+ },
+ gpl2_only => {
+ desc => "GPL version 2 only",
+ can_subsume => {
+ gpl_any => 1,
+ gpl2_or_later => 1,
+ public_domain => 1,
+ bsd3 => 1,
+ bsd2 => 1,
+ mit => 1,
+ isc => 1,
+ },
+ },
+ public_domain => {
+ desc => "Public Domain",
+ can_subsume => {},
+ },
+ bsd4 => {
+ desc => "BSD Licence (with advertising clause)",
+ can_subsume => {
+ public_domain => 1,
+ bsd3 => 1,
+ bsd2 => 1,
+ mit => 1,
+ isc => 1,
+ },
+ },
+ bsd3 => {
+ desc => "BSD Licence (without advertising clause)",
+ can_subsume => {
+ public_domain => 1,
+ bsd2 => 1,
+ mit => 1,
+ isc => 1,
+ },
+ },
+ bsd2 => {
+ desc => "BSD Licence (without advertising or endorsement clauses)",
+ can_subsume => {
+ public_domain => 1,
+ mit => 1,
+ isc => 1,
+ },
+ },
+ mit => {
+ desc => "MIT/X11/Xorg Licence",
+ can_subsume => {
+ public_domain => 1,
+ isc => 1,
+ },
+ },
+ isc => {
+ desc => "ISC Licence",
+ can_subsume => {
+ public_domain => 1,
+ },
+ },
+};
+
+# Parse command-line options
+my $verbosity = 1;
+Getopt::Long::Configure ( 'bundling', 'auto_abbrev' );
+GetOptions (
+ 'verbose|v+' => sub { $verbosity++; },
+ 'quiet|q+' => sub { $verbosity--; },
+) or die "Could not parse command-line options\n";
+
+# Parse licence list from command line
+my $licences = {};
+foreach my $licence ( @ARGV ) {
+ die "Unknown licence \"$licence\"\n"
+ unless exists $known_licences->{$licence};
+ $licences->{$licence} = $known_licences->{$licence};
+}
+die "No licences specified\n" unless %$licences;
+
+# Dump licence list
+if ( $verbosity >= 1 ) {
+ print "The following licences appear within this file:\n";
+ foreach my $licence ( keys %$licences ) {
+ print " ".$licences->{$licence}->{desc}."\n"
+ }
+}
+
+# Apply licence compatibilities to reduce to a single resulting licence
+foreach my $licence ( keys %$licences ) {
+ # Skip already-deleted licences
+ next unless exists $licences->{$licence};
+ # Subsume any subsumable licences
+ foreach my $can_subsume ( keys %{$licences->{$licence}->{can_subsume}} ) {
+ if ( exists $licences->{$can_subsume} ) {
+ print $licences->{$licence}->{desc}." subsumes ".
+ $licences->{$can_subsume}->{desc}."\n"
+ if $verbosity >= 1;
+ delete $licences->{$can_subsume};
+ }
+ }
+}
+
+# Print resulting licence
+die "Cannot reduce to a single resulting licence!\n"
+ if ( keys %$licences ) != 1;
+( my $licence ) = keys %$licences;
+print "The overall licence for this file is:\n " if $verbosity >= 1;
+print $licences->{$licence}->{desc}."\n";
diff --git a/gpxe/src/util/makerom.pl b/gpxe/src/util/makerom.pl
index aed3a569..68c3be98 100755
--- a/gpxe/src/util/makerom.pl
+++ b/gpxe/src/util/makerom.pl
@@ -130,14 +130,14 @@ sub writerom ($$) {
close(R);
}
-sub checksum ($) {
- my ($romref) = @_;
+sub checksum ($$) {
+ my ($romref, $romsize) = @_;
substr($$romref, 6, 1) = "\x00";
- my $sum = unpack('%8C*', $$romref);
+ my $sum = unpack('%8C*', substr($$romref, 0, $romsize));
substr($$romref, 6, 1) = chr(256 - $sum);
# Double check
- $sum = unpack('%8C*', $$romref);
+ $sum = unpack('%8C*', substr($$romref, 0, $romsize));
if ($sum != 0) {
print "Checksum fails\n"
} elsif ($opts{'v'}) {
@@ -146,10 +146,10 @@ sub checksum ($) {
}
sub makerom () {
- my ($rom, $romsize);
+ my ($rom, $romsize, $stubsize);
- getopts('3xi:p:s:v', \%opts);
- $ARGV[0] or die "Usage: $0 [-s romsize] [-i ident] [-p vendorid,deviceid] [-x] [-3] rom-file\n";
+ getopts('3xni:p:s:v', \%opts);
+ $ARGV[0] or die "Usage: $0 [-s romsize] [-i ident] [-p vendorid,deviceid] [-n] [-x] [-3] rom-file\n";
open(R, $ARGV[0]) or die "$ARGV[0]: $!\n";
# Read in the whole ROM in one gulp
my $filesize = read(R, $rom, MAXROMSIZE+1);
@@ -183,10 +183,16 @@ sub makerom () {
}
# Pad with 0xFF to $romsize
$rom .= "\xFF" x ($romsize - length($rom));
- if ($romsize >= 128 * 1024) {
- print "Warning: ROM size exceeds extension BIOS limit\n";
+ # If this is a stub ROM, don't force header size to the full amount
+ if (!$opts{'n'}) {
+ if ($romsize >= 128 * 1024) {
+ print "Warning: ROM size exceeds extension BIOS limit\n";
+ }
+ substr($rom, 2, 1) = chr(($romsize / 512) % 256);
+ } else {
+ $stubsize = ord(substr($rom, 2, 1)) * 512;
+ print "Stub size is $stubsize\n" if $opts{'v'};
}
- substr($rom, 2, 1) = chr(($romsize / 512) % 256);
print "ROM size is $romsize\n" if $opts{'v'};
# set the product string only if we don't have one yet
my $pnp_hdr_offset = unpack('v', substr($rom, PNP_PTR_LOC, 2));
@@ -196,7 +202,7 @@ sub makerom () {
# 3c503 requires last two bytes to be 0x80
substr($rom, MINROMSIZE-2, 2) = "\x80\x80"
if ($opts{'3'} and $romsize == MINROMSIZE);
- checksum(\$rom);
+ checksum(\$rom, $opts{'n'} ? $stubsize : $romsize);
writerom($ARGV[0], \$rom);
}
@@ -213,7 +219,7 @@ sub modrom () {
print "$filesize bytes read\n" if $opts{'v'};
pcipnpheaders(\$rom, undef);
undiheaders(\$rom);
- checksum(\$rom);
+ checksum(\$rom, ord(substr($rom, 2, 1)) * 512);
writerom($ARGV[0], \$rom);
}
diff --git a/gpxe/src/util/modrom.pl b/gpxe/src/util/modrom.pl
index 695468c2..cdac0b97 100755
--- a/gpxe/src/util/modrom.pl
+++ b/gpxe/src/util/modrom.pl
@@ -131,9 +131,9 @@ sub writerom ($$) {
sub checksum ($) {
my ($romref) = @_;
- substr($$romref, 5, 1) = "\x00";
+ substr($$romref, 6, 1) = "\x00";
my $sum = unpack('%8C*', $$romref);
- substr($$romref, 5, 1) = chr(256 - $sum);
+ substr($$romref, 6, 1) = chr(256 - $sum);
# Double check
$sum = unpack('%8C*', $$romref);
if ($sum != 0) {
diff --git a/gpxe/src/util/padimg.pl b/gpxe/src/util/padimg.pl
new file mode 100755
index 00000000..4421aaf4
--- /dev/null
+++ b/gpxe/src/util/padimg.pl
@@ -0,0 +1,44 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+use Getopt::Long;
+use Fcntl;
+
+my $verbosity = 0;
+my $blksize = 512;
+my $byte = 0;
+
+my %opts = (
+ 'verbose|v+' => sub { $verbosity++; },
+ 'quiet|q+' => sub { $verbosity--; },
+ 'blksize|s=o' => sub { $blksize = $_[1]; },
+ 'byte|b=o' => sub { $byte = $_[1]; },
+);
+
+Getopt::Long::Configure ( 'bundling', 'auto_abbrev' );
+GetOptions ( %opts ) or die "Could not parse command-line options\n";
+
+while ( my $filename = shift ) {
+ die "$filename is not a file\n" unless -f $filename;
+ my $oldsize = -s $filename;
+ my $padsize = ( ( -$oldsize ) % $blksize );
+ my $newsize = ( $oldsize + $padsize );
+ next unless $padsize;
+ if ( $verbosity >= 1 ) {
+ printf "Padding %s from %d to %d bytes with %d x 0x%02x\n",
+ $filename, $oldsize, $newsize, $padsize, $byte;
+ }
+ if ( $byte ) {
+ sysopen ( my $fh, $filename, ( O_WRONLY | O_APPEND ) )
+ or die "Could not open $filename for appending: $!\n";
+ syswrite $fh, ( chr ( $byte ) x $padsize )
+ or die "Could not append to $filename: $!\n";
+ close ( $fh );
+ } else {
+ truncate $filename, $newsize
+ or die "Could not resize $filename: $!\n";
+ }
+ die "Failed to pad $filename\n"
+ unless ( ( ( -s $filename ) % $blksize ) == 0 );
+}
diff --git a/gpxe/src/util/parserom.pl b/gpxe/src/util/parserom.pl
index 3d41b544..578eb1dc 100644
--- a/gpxe/src/util/parserom.pl
+++ b/gpxe/src/util/parserom.pl
@@ -45,7 +45,8 @@ while ( <DRV> ) {
\s*0x([0-9A-Fa-f]{4})\s*, # PCI vendor
\s*0x([0-9A-Fa-f]{4})\s*, # PCI device
\s*\"([^\"]*)\"\s*, # Image
- \s*\"([^\"]*)\"\s* # Description
+ \s*\"([^\"]*)\"\s*, # Description
+ \s*.*\s* # Driver data
\)/x ) {
( my $vendor, my $device, my $image, my $desc ) = ( lc $1, lc $2, $3, $4 );
rom ( "pci", $image, $desc, $vendor, $device );
diff --git a/gpxe/src/util/zbin.c b/gpxe/src/util/zbin.c
index c1082b31..707ae995 100644
--- a/gpxe/src/util/zbin.c
+++ b/gpxe/src/util/zbin.c
@@ -38,7 +38,7 @@ struct zinfo_pack {
uint32_t align;
};
-struct zinfo_subtract {
+struct zinfo_add {
char type[4];
uint32_t offset;
uint32_t divisor;
@@ -49,7 +49,7 @@ union zinfo_record {
struct zinfo_common common;
struct zinfo_copy copy;
struct zinfo_pack pack;
- struct zinfo_subtract subtract;
+ struct zinfo_add add;
};
struct zinfo_file {
@@ -57,6 +57,10 @@ struct zinfo_file {
unsigned int num_entries;
};
+static unsigned long align ( unsigned long value, unsigned long align ) {
+ return ( ( value + align - 1 ) & ~( align - 1 ) );
+}
+
static int read_file ( const char *filename, void **buf, size_t *len ) {
FILE *file;
struct stat stat;
@@ -77,13 +81,13 @@ static int read_file ( const char *filename, void **buf, size_t *len ) {
*len = stat.st_size;
*buf = malloc ( *len );
if ( ! *buf ) {
- fprintf ( stderr, "Could not malloc() %d bytes for %s: %s\n",
+ fprintf ( stderr, "Could not malloc() %zd bytes for %s: %s\n",
*len, filename, strerror ( errno ) );
goto err;
}
if ( fread ( *buf, 1, *len, file ) != *len ) {
- fprintf ( stderr, "Could not read %d bytes from %s: %s\n",
+ fprintf ( stderr, "Could not read %zd bytes from %s: %s\n",
*len, filename, strerror ( errno ) );
goto err;
}
@@ -111,7 +115,7 @@ static int read_zinfo_file ( const char *filename,
return -1;
if ( ( len % sizeof ( *(zinfo->zinfo) ) ) != 0 ) {
- fprintf ( stderr, ".zinfo file %s has invalid length %d\n",
+ fprintf ( stderr, ".zinfo file %s has invalid length %zd\n",
filename, len );
return -1;
}
@@ -126,7 +130,7 @@ static int alloc_output_file ( size_t max_len, struct output_file *output ) {
output->max_len = ( max_len );
output->buf = malloc ( max_len );
if ( ! output->buf ) {
- fprintf ( stderr, "Could not allocate %d bytes for output\n",
+ fprintf ( stderr, "Could not allocate %zd bytes for output\n",
max_len );
return -1;
}
@@ -140,22 +144,22 @@ static int process_zinfo_copy ( struct input_file *input,
struct zinfo_copy *copy = &zinfo->copy;
size_t offset = copy->offset;
size_t len = copy->len;
- unsigned int align = copy->align;
if ( ( offset + len ) > input->len ) {
fprintf ( stderr, "Input buffer overrun on copy\n" );
return -1;
}
- output->len = ( ( output->len + align - 1 ) & ~( align - 1 ) );
+ output->len = align ( output->len, copy->align );
if ( ( output->len + len ) > output->max_len ) {
fprintf ( stderr, "Output buffer overrun on copy\n" );
return -1;
}
if ( DEBUG ) {
- fprintf ( stderr, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n", offset, ( offset + len ),
- output->len, ( output->len + len ) );
+ fprintf ( stderr, "COPY [%#zx,%#zx) to [%#zx,%#zx)\n",
+ offset, ( offset + len ), output->len,
+ ( output->len + len ) );
}
memcpy ( ( output->buf + output->len ),
@@ -170,7 +174,6 @@ static int process_zinfo_pack ( struct input_file *input,
struct zinfo_pack *pack = &zinfo->pack;
size_t offset = pack->offset;
size_t len = pack->len;
- unsigned int align = pack->align;
unsigned long packed_len;
if ( ( offset + len ) > input->len ) {
@@ -178,7 +181,7 @@ static int process_zinfo_pack ( struct input_file *input,
return -1;
}
- output->len = ( ( output->len + align - 1 ) & ~( align - 1 ) );
+ output->len = align ( output->len, pack->align );
if ( output->len > output->max_len ) {
fprintf ( stderr, "Output buffer overrun on pack\n" );
return -1;
@@ -192,8 +195,9 @@ static int process_zinfo_pack ( struct input_file *input,
}
if ( DEBUG ) {
- fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n", offset, ( offset + len ),
- output->len, ( output->len + packed_len ) );
+ fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n",
+ offset, ( offset + len ), output->len,
+ ( size_t )( output->len + packed_len ) );
}
output->len += packed_len;
@@ -205,76 +209,102 @@ static int process_zinfo_pack ( struct input_file *input,
return 0;
}
-static int process_zinfo_subtract ( struct input_file *input,
- struct output_file *output,
- struct zinfo_subtract *subtract,
- size_t datasize ) {
- size_t offset = subtract->offset;
+static int process_zinfo_add ( struct input_file *input,
+ struct output_file *output,
+ struct zinfo_add *add,
+ size_t datasize ) {
+ size_t offset = add->offset;
void *target;
- long delta;
- unsigned long old;
- unsigned long new;
+ signed long addend;
+ unsigned long size;
+ signed long val;
+ unsigned long mask;
if ( ( offset + datasize ) > output->len ) {
- fprintf ( stderr, "Subtract at %#zx outside output buffer\n",
+ fprintf ( stderr, "Add at %#zx outside output buffer\n",
offset );
return -1;
}
target = ( output->buf + offset );
- delta = ( ( output->len / subtract->divisor ) -
- ( input->len / subtract->divisor ) );
+ size = ( align ( output->len, add->divisor ) / add->divisor );
switch ( datasize ) {
- case 1: {
- uint8_t *byte = target;
- old = *byte;
- *byte += delta;
- new = *byte;
- break; }
- case 2: {
- uint16_t *word = target;
- old = *word;
- *word += delta;
- new = *word;
- break; }
- case 4: {
- uint32_t *dword = target;
- old = *dword;
- *dword += delta;
- new = *dword;
- break; }
+ case 1:
+ addend = *( ( int8_t * ) target );
+ break;
+ case 2:
+ addend = *( ( int16_t * ) target );
+ break;
+ case 4:
+ addend = *( ( int32_t * ) target );
+ break;
default:
- fprintf ( stderr, "Unsupported subtract datasize %d\n",
+ fprintf ( stderr, "Unsupported add datasize %zd\n",
datasize );
return -1;
}
+ val = size + addend;
+
+ /* The result of 1UL << ( 8 * sizeof(unsigned long) ) is undefined */
+ mask = ( ( datasize < sizeof ( mask ) ) ?
+ ( ( 1UL << ( 8 * datasize ) ) - 1 ) : ~0UL );
+
+ if ( val < 0 ) {
+ fprintf ( stderr, "Add %s%#x+%#lx at %#zx %sflows field\n",
+ ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
+ offset, ( ( addend < 0 ) ? "under" : "over" ) );
+ return -1;
+ }
+
+ if ( val & ~mask ) {
+ fprintf ( stderr, "Add %s%#x+%#lx at %#zx overflows %zd-byte "
+ "field (%d bytes too big)\n",
+ ( ( addend < 0 ) ? "-" : "" ), abs ( addend ), size,
+ offset, datasize,
+ ( int )( ( val - mask - 1 ) * add->divisor ) );
+ return -1;
+ }
+
+ switch ( datasize ) {
+ case 1:
+ *( ( uint8_t * ) target ) = val;
+ break;
+ case 2:
+ *( ( uint16_t * ) target ) = val;
+ break;
+ case 4:
+ *( ( uint32_t * ) target ) = val;
+ break;
+ }
+
if ( DEBUG ) {
- fprintf ( stderr, "SUBx [%#zx,%#zx) (%#lx+(%#lx/%#lx)-(%#lx/%#lx)) = %#lx\n",
- offset, ( offset + datasize ), old, output->len, subtract->divisor,
- input->len, subtract->divisor, new );
+ fprintf ( stderr, "ADDx [%#zx,%#zx) (%s%#x+(%#zx/%#x)) = "
+ "%#lx\n", offset, ( offset + datasize ),
+ ( ( addend < 0 ) ? "-" : "" ), abs ( addend ),
+ output->len, add->divisor, val );
}
return 0;
}
-static int process_zinfo_subb ( struct input_file *input,
+static int process_zinfo_addb ( struct input_file *input,
struct output_file *output,
union zinfo_record *zinfo ) {
- return process_zinfo_subtract ( input, output, &zinfo->subtract, 1 );
+ return process_zinfo_add ( input, output, &zinfo->add, 1 );
}
-static int process_zinfo_subw ( struct input_file *input,
+static int process_zinfo_addw ( struct input_file *input,
struct output_file *output,
union zinfo_record *zinfo ) {
- return process_zinfo_subtract ( input, output, &zinfo->subtract, 2 );
+ return process_zinfo_add ( input, output, &zinfo->add, 2 );
}
-static int process_zinfo_subl ( struct input_file *input,
+static int process_zinfo_addl ( struct input_file *input,
struct output_file *output,
union zinfo_record *zinfo ) {
- return process_zinfo_subtract ( input, output, &zinfo->subtract, 4 );
+ return process_zinfo_add ( input, output, &zinfo->add, 4 );
}
struct zinfo_processor {
@@ -287,9 +317,9 @@ struct zinfo_processor {
static struct zinfo_processor zinfo_processors[] = {
{ "COPY", process_zinfo_copy },
{ "PACK", process_zinfo_pack },
- { "SUBB", process_zinfo_subb },
- { "SUBW", process_zinfo_subw },
- { "SUBL", process_zinfo_subl },
+ { "ADDB", process_zinfo_addb },
+ { "ADDW", process_zinfo_addw },
+ { "ADDL", process_zinfo_addl },
};
static int process_zinfo ( struct input_file *input,
@@ -314,7 +344,7 @@ static int process_zinfo ( struct input_file *input,
static int write_output_file ( struct output_file *output ) {
if ( fwrite ( output->buf, 1, output->len, stdout ) != output->len ) {
- fprintf ( stderr, "Could not write %d bytes of output: %s\n",
+ fprintf ( stderr, "Could not write %zd bytes of output: %s\n",
output->len, strerror ( errno ) );
return -1;
}