PaX and W^X use segmentation on x86. x86 code segments were by design and definition non-writable--you couldn't write to any region in a code segment unless a writable data or stack segment overlapped the same region. This was a deliberate feature of the hardware that happened to go unused in favor of flat memory models in the most popular operating systems.