Adds a new option -satisfy_w_xor_x and implements it for Linux. It uses a dual-map approach to satisfy write-xor-execute security policies. A writable shadow is created for the vmcode region, while vmcode itself is read-only. A constant offset is then used to translate between writable and executable addresses.
The dual mapping uses memfd_create if available, falling back to shm if not, for the file backing. The scheme relies on a single large, now-separated-from-vmheap vmcode in order to have a single mirrored region. If vmcode is left as the default 1G size, the scheme simply fails if vmcode runs out of space: the user must request 2G up front (with corresponding loss of -vm_base_near_app: see #3570) for such a huge application.
Generated code and the code cache store executable addresses, converting to writable on every write. Special heap units store writable addresses and convert to executable when passing to the user.
Committing new memory uses a fixed mmap of the mapping file, instead of mprotect, since most W^X policies do not allow execution after mprotect.
Adds a new w_xor_x test.
Updates syscall_linux_x86.h with numbers from FC27 to include SYS_memfd_create.
No support is yet provided for Windows, for Mac, for 32-bit, or for persistent caches.
Issue: #3566 (closed), #3570