Every object is cut into pages of the header’s page size. The object page table has one
entry for each page of the module, as many as the header’s page count
(0x14), at its object page table offset (0x48, from the start
of the LE header). Each object names its first entry and how many it has; see
The object table. Entries are numbered from
1.
Page entry
An LE page entry is 4 bytes:
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 3 | Page number | The page’s number in the file, from 1, stored high byte first. |
| 3 | 1 | Type | The kind of page. |
Stored pages lie one after another in the file, all of the page size except the last. The page with number n is at:
file offset = data pages offset + (n − 1) × page size
size = page size, or the header’s “bytes in the last page” for the highest number
The byte order of the page number is unusual. Open Watcom’s linker writes it high byte
first (loadflat.c) and its wdump reads it the same way; Wine’s
winedump reads the same bytes as a 16-bit word and a byte, which gives the
same number while it is below 256. The explorer reads it high byte first. No file
examined for this site has 256 pages or more, so the difference has not been tested
on a real file.
This entry is what LX replaced: an LX entry is 8 bytes, with its own offset and size, so that pages can be any length and anywhere in the file.
Page types
| Value | Type | Meaning |
|---|---|---|
| 0 | Legal physical page | Stored in the file. |
| 1 | Iterated data page | Stored in a compact form; see Iterated pages. |
| 2 | Invalid page | Not stored in the file. |
| 3 | Zero-filled page | Not stored; loaded as zeros. |
| 4 | Range of pages | Listed by IBM and Open Watcom, without more detail. |
These are the values Open Watcom shares between LE and LX, and IBM gives for LX. The explorer shows the bytes of type-0 pages only.
The pages
The pages start at the header’s data pages offset (0x80, a file offset).
The explorer groups the pages of each object that lie one after another in the file
into one block, named after the object, and lists the pages inside it. The executable
objects’ pages are the ones it disassembles. A page holds the object’s bytes from
j × page size on, before fixups are applied: the
fixups say what to patch.
Iterated pages
An iterated page is stored as records that rebuild it. In IBM’s description for LX,
each record is a 16-bit repeat count, a 16-bit length, and that many bytes of pattern,
repeated count times. The header’s iterated data map offset (0x4C) is a
file offset. The explorer does not show the bytes of iterated pages in LE files.
Per-page checksums
If the header’s per-page checksum offset (0x7C) is not 0, it points to a
table of 32-bit checksums, one for each page. The explorer shows them without checking
them.
Worked example
00000174 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 00
00000184 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00
…
000001C4 00 00 15 00 00 00 16 00 00 00 17 00
The header gives a page size of 512, data pages at 0x1000 and 91 bytes in
the last page. Page 1 is at 0x1000, page 2 at 0x1200, and
page 23, the only page of object 2, at 0x1000 + 22 × 512 = 0x3C00, 91 bytes
long.