@pervognsen I think the relevant project in this area is Segue.¹ The paper discusses implementations in wasm2c² and WAMR.³ Apparently one challenge is that Windows trashes the segment registers on context switches.⁴
Shravan is on here (@shravanrn) and would have a lot more insight than I do!
__
¹ S. Narayan et al., “Segue & ColorGuard: Optimizing SFI Performance and Scalability on Modern Architectures,” in proc. ASPLOS 2025. Online: https://shravanrn.com/pubs/seguecg.pdf
² https://github.com/WebAssembly/wabt/blob/main/wasm2c/wasm-rt.h#L205-L254
³ https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/perf_tune.md?plain=1#L23-L53
⁴ Raymond Chen says, “[t]he Windows ABI forbids modifying either of these segment registers,” https://devblogs.microsoft.com/oldnewthing/20220831-00/?p=107077
@hovav @pervognsen
Firefox on Linux x86-64 uses the gsbase for rlbox library sandboxing [1] because we got a pretty nice perf boost --- eliminates roughly 75% of wasm's overhead on some workloads [2] (but to be clear, it is not used by Firefox's Wasm JIT to run Wasm in websites)
Re your question about possible negative displacements --- given that Wasm's memory op supports an linear memory offset specified as the sum of 32-bit variable `offset` and 32-bit `constant`, the straightforward encoding `gs: constant(%reg_offset)` is possible only when the constant is <= INT32_MAX (which is true most of the time).
If we run into a larger constant than that, I expect that we just fall back to using two instructions
```
reg_tmp = offset + constant
val = gs:reg_tmp
```
The nice bit is that the wasm2c implementation doesn't really need to think about any of this, and can just defer to clang due to the `__seg_gs` syntax [3] i.e., named address space support :)
[1] https://hacks.mozilla.org/2021/12/webassembly-and-back-again-fine-grained-sandboxing-in-firefox-95/
[2] https://shravanrn.com/pubs/seguecg.pdf
[3] https://github.com/WebAssembly/wabt/blob/main/src/template/wasm2c.declarations.c#L55C48-L55C56
@hovav @pervognsen Re challenges:
- As hovav mentioned, the windows kernel trashing the segment registers is a blocking issue on using this approach in Windows (I *think* it shouldn't be too hard to fix this in the kernel if someone from Microsoft wanted to do this :) )
- wasm2c specific issue --- Unlike clang, GCC's named address space support is not as complete. For example, GCC doesn't allow `memcpy` when the source or destination is a named address space pointer (__seg_gs_ pointer). Thus, for now, wasm2c code can only use gs_base when the wasm2c output is compiled with clang. Should be fixable with some extra named-address space support in GCC.
- For use for Firefox, I needed to implement both a fast version that sets the gs_base using the `wrgsbase` instruction when available and a slower fallback of doing this through system calls for hardware lacking this instruction --- the slower syscall version can unfortunately introduce some overheads depending on how often you need to switch between Wasm modules.