Uninformed: Informative Information for the Uninformed

Vol 4» 2006.Jun

Unwind Information

For the purpose of unwinding call frames and dispatching exceptions, each non-leaf function has some non-zero amount of unwind information associated with it. This association is made through the UnwindInfoAddress attribute of the IMAGE_RUNTIME_FUNCTION_ENTRY structure. The UnwindInfoAddress itself is an RVA that points to an UNWIND_INFO structure which is defined as[8]:

typedef struct _UNWIND_INFO {
    UBYTE Version       : 3;
    UBYTE Flags         : 5;
    UBYTE SizeOfProlog;
    UBYTE CountOfCodes;
    UBYTE FrameRegister : 4;
    UBYTE FrameOffset   : 4;
    UNWIND_CODE UnwindCode[1];
/*  UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
*   union {
*       OPTIONAL ULONG ExceptionHandler;
*       OPTIONAL ULONG FunctionEntry;
*   };
*   OPTIONAL ULONG ExceptionData[]; */

This structure, at a very high level, describes a non-leaf function in terms of its prologue size and frame register usage. Furthermore, it describes the way in which the stack is set up when the prologue for this non-leaf function is executed. This is provided through an array of codes as accessed through the UnwindCode array. This array is composed of UNWIND_CODE structures which are defined as[8]:

typedef union _UNWIND_CODE {
    struct {
        UBYTE CodeOffset;
        UBYTE UnwindOp : 4;
        UBYTE OpInfo   : 4;
    USHORT FrameOffset;

In order to properly unwind a frame, the exception dispatcher needs to be aware of the amount of stack space allocated in that frame, the locations of saved non-volatile registers, and anything else that has to do with the stack. This information is necessary in order to be able to restore the caller's stack frame when an unwind operation occurs. By having the compiler keep track of this information at link time, it's possible to emulate the unwind process by inverting the operations described in the unwind code array for a given non-leaf function.

Aside from conveying stack frame set up, the UNWIND_INFO structure may also describe exception handling information, such as the exception handler that is to be called if an exception occurs. This information is conveyed through the ExceptionHandler and ExceptionData attributes of the structure which exist only if the UNW_FLAG_EHANDLER flag is set in the Flags field.

For more details on the format and use of these structures for unwinding as well as a complete description of the unwind process, please refer to the MSDN documentation[2].