Code and data segments follow the Windows header. Some of the code segments may contain calls to functions in other segments and may, therefore, require relocation data to resolve those references. This relocation data is stored in a relocation table that appears immediately after the code or data in the segment. The first 2 bytes in this table specify the number of relocation items the table contains. A relocation item is a collection of bytes specifying the following information:
Address type (segment only, offset only, segment and offset)
Relocation type (internal reference, imported ordinal, imported name)
Segment number or ordinal identifier (for internal references)
Reference-table index or function ordinal number (for imported ordinals)
Reference-table index or name-table offset (for imported names)
Each relocation item contains 8 bytes of data, the first byte of which specifies one of the following relocation-address types:
Value | Meaning |
0 | Low byte at the specified offset |
2 | 16-bit selector |
3 | 32-bit pointer |
5 | 16-bit offset |
11 | 48-bit pointer |
13 | 32-bit offset |
The second byte specifies one of the following relocation types:
Value | Meaning |
0 | Internal reference |
1 | Imported ordinal |
2 | Imported name |
3 | OSFIXUP |
The third and fourth bytes specify the offset of the relocation item within the segment.
If the relocation type is imported ordinal, the fifth and sixth bytes specify an index to a module's reference table and the seventh and eighth bytes specify a function ordinal value.
If the relocation type is imported name, the fifth and sixth bytes specify an index to a module's reference table and the seventh and eighth bytes specify an offset to an imported-name table.
If the relocation type is internal reference and the segment is fixed, the fifth byte specifies the segment number, the sixth byte is zero, and the seventh and eighth bytes specify an offset to the segment. If the relocation type is internal reference and the segment is movable, the fifth byte specifies 0FFh, the sixth byte is zero; and the seventh and eighth bytes specify an ordinal value found in the segment's entry table.