- The paper introduces a novel shadow stack mechanism that repurposes ARM Cortex-M's DWT to enforce robust control-flow protection.
- It utilizes dynamic switching between read-only and writable access to the shadow stack, maintaining low runtime overhead (1.81% to 7.33%) and minimal code size increase.
- The approach secures normal and exception call/return paths without relying on MPUs or TEEs, ensuring comprehensive defense for embedded systems.
WATSON: Data Watchpoint-based Shadow Stack Protection for Embedded Systems
Introduction and Motivation
The security of embedded systems and IoT devices is highly constrained by the absence of comprehensive memory protection, the omnipresence of memory-unsafe C code, and strict real-time performance requirements. Return-oriented programming (ROP) and related control-flow hijacking attacks remain effective against such platforms, with shadow stacks being one of the only architecturally generalizable defenses. However, practically deployed shadow stacks are often defeated by lack of (1) system-wide enforcement, (2) efficient and fine-grained write protection on platforms without MMUs or with limited MPUs, and (3) compatibility with other critical security mechanisms. Most prior approaches either incur high runtime overhead, require TEEs unavailable on commodity hardware, or consume scarce hardware resources (comparators, MPU regions) needed by other defenses.
WATSON proposes a robust shadow stack mechanism for bare-metal and RTOS-based embedded systems, leveraging the data watchpoint and trace (DWT) unit commonly present in modern ARM Cortex-M MCUs. Unlike methods using MPUs or TrustZone, WATSON uses debug hardware intended for development-phase tracing, offering fine-grained and dynamic run-time switching between read-only and writable access to the shadow stack memory. This design enables efficient control-flow enforcement across both normal and exceptional (interrupt/handler) call/return paths, while remaining compatible with parallel compartmentalization schemes and existing debugging/profiling workflows. Practical evaluation on industry-standard microcontrollers demonstrates low single-digit runtime overheads, low code size increases, and strong protection against control-flow hijack attempts.
WATSON Design
System Architecture and Threat Model
WATSON targets single-core ARM Cortex-M systems with a hardware debug unit exposing a set of address comparators (DWT). The system runs bare-metal or simple RTOS, with all code in a single address space, and assumes arbitrary memory corruption is possible except for in the platform HAL. The adversary is assumed capable of writing to any location in RAM, with full knowledge of memory layout, and of corrupting return addresses and/or the metadata region holding the shadow stack.
Shadow Stack Instrumentation
Each function is instrumented at the IR level (LLVM pass) such that:
- On entry, the callee stores the return address into a dedicated compact shadow stack, updating the shadow stack pointer (
ssp).
- On return, the callee loads the address from the shadow stack, verifies its correctness, and modifies
ssp accordingly.
Rather than reserving a GPR for ssp (which is infeasible on Cortex-M due to register scarcity), WATSON repurposes a memory-mapped DWT register as an unforgeable, write-protected shadow stack pointer. This approach is minimally intrusive, minimizes register pressure, and is compatible with existing HALs and inlined assembly code.


Figure 1: (a) The function call graph and exception control-flow structure of the platform. (b) A compact (address-only) shadow stack layout maintained by the instrumented prologues/epilogues.
Fine-Grained Runtime Enforcement
Write protection of the shadow stack is achieved using the DWT comparators:
- By default, the shadow stack region is write-protected. Any unauthorized write triggers a
DebugMon exception, leading to system reset or alert (policy).
- Before writing a new address in a function prologue, WATSON momentarily and minimally disables protection, writes the return address and advances
ssp, then restores the strict write-protected mode before function body execution.
Exception entries/exits are instrumented as well, copying relevant parts of the exception stack frame to/from the shadow stack to prevent handler hijacking, addressing privilege escalation vectors not covered by prior stack-based schemes.

Figure 2: Compiler and runtime workflow—WATSON-specific enforcement mechanisms are highlighted.
Systematic Exception and Interrupt Handling
ARM Cortex-M platforms use automatic hardware stacking on exception entry and unstacking on return. WATSON extends coverage by instrumenting exception prologues and epilogues, storing and restoring partial register frames in the shadow stack, ensuring return address and register integrity even if an adversary controls a buggy interrupt handler.
Implementation
A full prototype (876 lines C++/LLVM, 56 lines system C) was integrated into the LLVM 9.0.1 backend. The implementation was evaluated on the STM32F469 (Cortex-M4, ARMv7-M, four DWT comparators, 128KB DWT coverage across regions). The compact shadow stack was set at 32KB—sufficient for >8K nested function activations, with the region and write triggers configured at system boot.
The mechanism is compatible with the use of the same debug registers for profiling/cycle counting, as required by most bare-metal firmware workflows.
Evaluation
WATSON’s average runtime overhead is 7.33% on BEEBS and 1.81% on CoreMark-Pro, with worst-case instance below that of prior work relying on privileged/secure world context switches (e.g., Silhouette, TzmCFI, CaRE). Performance stability across benchmarks is high, and targeted code instrumentation for exception handling ensures that interrupt/exception throughput remains unaffected except at microbenchmark granularity.

Figure 3: Breakdown of CPU cycles per operation for instrumentation (AW: access watchdog, USS: update stack, ASSP: adjust pointer, Other).
Code Size Overhead
Average code size increase is 8.58% (geometric mean 7.36%) across BEEBS, 2-3% on CoreMark-Pro, and ≤2.1% on real-world firmware applications. The majority of this overhead is attributable to instrumentation of ssp management. The approach does not increase data footprint significantly, and memory costs are dominated by shadow stack sizing, as determined by comparator region length and function nesting requirements.

Figure 4: Code size overhead incurred by WATSON’s instrumentation for all programs in the BEEBS benchmark.
Security Guarantees
- Attempts to overwrite the return address on the main stack are always detected and blocked at return, since the canonical return address is fetched from the protected shadow stack.
- Direct, out-of-bounds writes to the shadow stack itself (given adversarial knowledge of its address) are always detected and forcibly terminated, as only legit prologues/epilogues can temporarily unlock write access.
- Each exception entry and return is fully covered, closing privilege escalation vectors left open by solutions that trusted all handler code a priori.
- The DWT-based enforcement is orthogonal and compatible with compartmentalization and other defense-in-depth strategies.
Comparison with Prior Work
- MPU-based approaches (RECFISH, Silhouette, Kage, SUM) are limited by small number of MPU regions and/or privilege separation assumptions, conflicting with parallel security policies.
- TEE-based solutions (CaRE, TzmCFI, RIO, Sherloc, InsectACIDE) incur high runtime overhead due to context switching and are incompatible with most commodity MCUs.
- DeTRAP uses debug triggers in RISC-V, but cannot easily repurpose GPRs or handle Cortex-M’s distributed handler model.
- WATSON remains compatible with profiling, is not dependent on TrustZone or MMU, and is deployable on existing hardware.
Practical and Theoretical Implications
Practically, WATSON enables deployment of robust control-flow defenses on resource-constrained, commodity embedded devices without requiring costly or unavailable security hardware. It substantially reduces the attack surface even in adversarial, memory-unsafe, monolithic codebases, and maintains compatibility with both legacy debugging/profiling workflows and advanced compartmentalization. The approach demonstrates that security-critical memory regions can be efficiently protected using general-purpose debug hardware, suggesting a template for future work integrating shadow stacks with other debug-feature-based monitoring (e.g., integrity attestation, protected function isolation).
Theoretically, WATSON provides a demonstration of how careful compiler/hardware co-design can bypass the traditional trade-off between protection strength and practical deployability on MCUs—a result that is likely extensible to future RISC-V and ARM developments as debug features evolve toward more granular machine-level mediation.
Conclusion
WATSON presents a practical, low-overhead method for system-wide shadow stack enforcement in embedded systems. By reusing ubiquitous debug hardware for write protection, it achieves compatibility with real systems while avoiding the limitations of privileged software, MPUs, or TEEs. Evaluation demonstrates system-wide integrity enforcement, average runtime overheads of 7.33% (BEEBS) and 1.81% (CoreMark-Pro), and ≤2.1% code size impact for real applications. The contribution points toward a direction for robust, extensible memory and control-flow protection grounded in generally available, developer-facing platform features (2605.08604).