[build] Fix signed/unsigned division in util/zbin.c
Commit b149a99 ([build] Round up SUBx deltas) introduced a
signed/unsigned issue that affects gPXE images built on 32-bit hosts.
The zbin fixup utility performed an unsigned division, which led to
.usb images with an incorrect number of sectors to load.
The issue snuck by on 64-bit hosts since uint32_t is promoted to long.
On 32-bit hosts it is promoted to unsigned long.
Modified-by: Michael Brown <mcb30@etherboot.org>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
The zbin compressor fixup utility rounds down file sizes before
calculating their difference. This produces incorrect values and may
cause truncated gPXE images to be loaded at boot.
The following example explains the problem:
ilen = 48 bytes (uncompressed input file)
olen = 17 bytes (compressed output file)
divisor = 16 bytes (paragraph granularity)
fixmeup = 3 paragraphs (value to fix up)
olen / divisor - ilen / divisor
= 1 - 3
= -2 paragraphs (old delta calculation)
( align ( olen, divisor ) - align ( ilen, divisor ) ) / divisor
= 2 - 3
= -1 paragraphs (new delta calculation)
If we perform the SUBx operation with old delta:
fixmeup + -2 = 1 paragraph gets loaded by the prefix
With the new delta:
fixmeup + -1 = 2 paragraphs get loaded by the prefix
The old delta calculation removes the last paragraph; the prefix will
load a truncated copy of gPXE into memory. We need to load 2
paragraphs since olen is 17 bytes. Loading only 1 paragraph (16
bytes) would truncate the last byte.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
Must check that argument to a fclose() is not NULL -- we can get to the
'err' label when file was not opened. fclose(NULL) is known to produce
core dump on some platforms and we don't want zbin to fail so loudly.
Signed-off-by: Eygene Ryabinkin <rea-fbsd@codelabs.ru>