# Through the Window: Exploitation and Countermeasures of the ESP32 Register Window Overflow +
## 3 The Xtensa Register Window Mechanism  
The Xtensa architecture has a configuration to use a register window mechanism. With this configuration, the regular number of 16 general-purpose registers a0-a15 stays the same, but is virtualized and backed up by a larger physical register set. The physical register set contains either 32 or 64 registers ar0-ar31/ar63, depending on the configuration.  
An example of such a mapping is illustrated in Figure 1. In the example, the mapping starts at register ar24 and ends at register ar39. The current mapping is changed when a new function is called, or a function returns. The direction is shown in the figure. The number of registers around which the register window is rotating depends on the call instruction that is used for a function call. In total, there are eight different call instructions for the Xtensa LX architecture, four for direct, and four for indirect calls. Each group contains call instructions to move the register window by either 0, 4, 8, or 12 registers. The instructions call10 and callx0, which do not move the register window, are only used within the call0 ABI. As the registers shift by at most 12 registers, there is always an overlapping between the old and new register windows. This is used to pass arguments and return values between the caller and the callee.  
In general, this mechanism increases code density and efficiency as it eliminates the necessity of saving and restoring register values in the prologue and epilogue of a function. With a new function, the register window can simply shift to a new set of registers. It is only limited by the number of physical registers. When a program reaches a certain call depth, there are no registers left that are not already in use. In such a case, the processor detects memory access to such a register and generates a window-overflow exception. Please note that the overflow is not generated when a function is called but only when a register that already belongs to a different window is accessed. The overflow exception is responsible for saving register values of the non-overlapping part of the register window to the stack before returning to the regular program flow. For example, in Figure 2, if _Function A_ with a corresponding register window \(W_{A}\) is calling _Function B_ using a call8 instruction and at a later points its register values are saved by a window overflow, a _WindowOverflow8_ handler is invoked, saving only registers a0-a7 of _Function A_. The other registers are overlapping with the window of _Function B_ and are therefore associated with its window \(W_{B}\).  
The processor keeps track of which windows are currently in the physical register set and which have been written to the stack. When a program returns from a function using a windowed return instruction retw, it is checked whether or not register values must  
Figure 1: Example of a register window mapping of logical registers a0–a15 to physical registers ar24–ar39.  
be loaded back into the physical register set or not. In such a case, a window underflow exception is invoked that restores all register contents.