IA64 PE/COFF (efi-app-ia64) image has bad VirtualSize field

Brian J. Johnson bjohnson@sgi.com
Fri Jan 2 18:25:00 GMT 2004

Somewhere between binutils- (RedHat AS2.1) and
binutils- (RedHat AS3), binutils' handling of the
VirtualSize field in PE/COFF section headers changed.
binutils- places a zero in this field, which ends up
causing an assertion failure in the EFI 1.02 PE+ loader used on SGI
Altix boxes.  As a result, the elilo-3.4 OS loader distributed with
AS3 doesn't work on Altix.  This problem doesn't seem to affect EFI
1.1, as used on most other vendors' machines.

I'm patching SGI's EFI to avoid the crash, but it still smells like a
binutils bug.

Here's the relevant portion of the binutils- compiled
elilo-3.4 binary:

00000180: 0000 0000 0000 0000 2e74 6578 7400 0000  .........text...
00000190: 0000 0000 0010 0000 00be 0200 0004 0000  ................
000001a0: 0000 0000 0000 0000 0000 0000 2000 0060  ............ ..`

The .text section header begins at file offset 0x188 with the section
name.  The VirtualSize field is 4 bytes at header offset 8 (file
offset 0x190):  0x00000000.  The VirtualAddress field follows at
offset 12 (file offset 0x0x194):  0x00001000, and the SizeOfRawData
field after that at offset 16 (file offset 0x198):  0x0002be00.
VirtualSize is zero.

Here's the header produced from the same sources by

00000180: 0000 0000 0000 0000 2e74 6578 7400 0000  .........text...
00000190: 90aa 0200 0010 0000 00ac 0200 c002 0000  ................
000001a0: 0000 0000 0000 0000 0000 0000 2000 0060  ............ ..`

VirtualSize is 0x0002aa90, VirtualAddress is 0x00001000, and
SizeOfRawData is 0x0002ac00.  VirtualSize looks more reasonable.

Here's Microsoft's documentation for these fields, from the Microsoft
Portable Executable and Common Object File Format Specification,
Revision 6.0 - February 1999, section 4:

|  VirtualSize
|    Total size of the section when loaded into memory.
|    If this value is greater than Size of Raw Data, the
|    section is zero-padded. This field is valid only for
|    executable images and should be set to 0 for object
|    files.
| VirtualAddress
|    For executable images this is the address of the first
|    byte of the section, when loaded into memory,
|    relative to the image base. For object files, this field
|    is the address of the first byte before relocation is
|    applied; for simplicity, compilers should set this to
|    zero. Otherwise, it is an arbitrary value that is
|    subtracted from offsets during relocation.
|  SizeOfRawData
|    Size of the section (object file) or size of the
|    initialized data on disk (image files). For executable
|    image, this must be a multiple of FileAlignment from
|    the optional header. If this is less than VirtualSize
|    the remainder of the section is zero filled. Because
|    this field is rounded while the VirtualSize field is not
|    it is possible for this to be greater than VirtualSize as
|    well. When a section contains only uninitialized data,
|    this field should be 0.

It looks to me like the VirtualSize field of a loadable section should
not be zero in an executable image, especially if SizeOfRawData is
non-zero.  (And a zero-sized .text section doesn't make much

Any idea what changed from binutils- to
binutils-, and how to fix it?


						Brian J. Johnson


  "Save the planet!  We don't have a backup copy"
                                           -- Forest Godfrey

More information about the Binutils mailing list