To handle an exception, Windows must be able to unwind the stack: to step back from
the function that failed to the one that called it, and so on. On most processors the
image describes every function for this in a table, the exception table, at data
directory 3 and in the .pdata section, sorted by function address.
32-bit x86 programs have no such table. They register their exception handlers at run
time, in a chain of records on the stack that starts at fs:[0], and the
image lists only which handlers are safe to call: see
safe exception handlers. So in a
PE32 file the exception table is found only for the other machines: 32-bit ARM Windows,
Windows CE, and the MIPS, Alpha and PowerPC versions of Windows NT. The form of the
entries depends on the machine.
ARM entries
32-bit ARM Windows (machine ARMNT, 0x01C4) uses an 8-byte entry,
RUNTIME_FUNCTION:
| Offset | Size | Type | Field | Meaning |
|---|---|---|---|---|
| 0 | 4 | u32 | BeginAddress | The RVA of the function’s start. |
| 4 | 4 | u32 | UnwindData | The low 2 bits are the Flag. Flag 0: the rest is the RVA of an .xdata record. Flag 1 or 2: the word itself is packed unwind data, for a function with a simple, standard prolog and epilog. |
On x64 and Itanium the entry is 12 bytes, with an EndAddress; those are 64-bit machines, whose images are PE32+.
ARM unwind information
An .xdata record, in .xdata or .rdata, starts with a
32-bit header:
| Bits | Field | Meaning |
|---|---|---|
| 0–17 | Function Length | The function’s length, in 2-byte units. |
| 18–19 | Vers | The version, 0. |
| 20 | X | 1 when an exception handler’s RVA follows the codes. |
| 21 | E | 1 when there is one epilogue, described in the header itself. |
| 22 | F | 1 when the record describes a fragment of a function, with no prologue. |
| 23–27 | Epilogue Count | The number of epilogue scopes, or with E, the index of the first unwind code of the one epilogue. |
| 28–31 | Code Words | The number of 4-byte words of unwind codes. |
When Epilogue Count and Code Words are both 0, a second word follows, with an Extended Epilogue Count (16 bits) and Extended Code Words (8 bits). Then come the epilogue scopes, 4 bytes each unless E is set; the unwind codes; and, with X, the handler’s RVA and the handler’s own data.
The explorer groups the records into one “Unwind information” part and shows the bytes between them, the handlers’ data, as “Handler data”, without decoding them.
ARM unwind codes
The unwind codes are a byte code that describes the prologue’s effect on the stack, last instruction first: which registers it pushed, how much stack it allocated, and where the frame pointer is. Microsoft’s ARM exception handling page lists the encodings. The explorer shows the epilogue scopes, codes and handler RVA together, as bytes.
Older entry forms
Windows CE on ARM, Thumb, SH3, SH4 and SH5 uses 8-byte entries:
| Offset | Size | Bits | Field | Meaning |
|---|---|---|---|---|
| 0 | 4 | – | BeginAddress | The virtual address of the function. |
| 4 | 4 | 0–7 | Prolog Length | The number of instructions in the prolog. |
| 8–29 | Function Length | The number of instructions in the function. | ||
| 30 | 32-bit Flag | 1 for 32-bit instructions, 0 for 16-bit ones. | ||
| 31 | Exception Flag | 1 when there is an exception handler for the function. |
MIPS, and as the explorer reads them Alpha and PowerPC, use 20-byte entries:
| Offset | Size | Type | Field | Meaning |
|---|---|---|---|---|
| 0 | 4 | u32 | BeginAddress | The virtual address of the function. |
| 4 | 4 | u32 | EndAddress | The virtual address of its end. |
| 8 | 4 | u32 | ExceptionHandler | The handler to call. |
| 12 | 4 | u32 | HandlerData | Data for the handler. |
| 16 | 4 | u32 | PrologEndAddress | The virtual address of the end of the prolog. |
For any other machine the explorer shows the exception table as bytes.