Full ASLR for Static Binaries!

	Using the x86_64 gs segment register.
		- No indirection!
		- Requires no changes in the kernel!
		- Combine the .data and .bss sections into one writable section.
		- Expose a read-only symbol using the linker that points to the beginning
			of the combined section.
		- Using mmap() remap the combined data section into a new random region.
		- munmap() the old region.
		- Set the gs segment register to point to the beginning of the random 
			section using a kernel system call.
		- All data access uses the new value in the gs segment register going
			forward.
		- Works with thread local storage too! Each thread uses it's own gs segment
			register to access global shared data. Assuming threads are using
			the fs segment register to access thread local variables.
		- Assuming the .text segment is PIC the .text and .rodata section can be
			randomized together.
		- Kernel randomizes the whole initial binary (assuming .text section is
			PIC) and the rest is done in userspace.

	Section Base Table (SBT):
		- Similar to the Global Offset Table (GOT).
		- Contains all sections used by the program.
		- Kernel later populates this table for each section.
		- Extra level of indirection similar to the GOT.
		- Linker computes an offset into each section when referencing data and
			computes the final address using the SBT entry for that section.
			mov rax, [rip + var@PCRELSBT] ; Relative load of section base.
			mov rax, [rax + var_offset]   ; Load var using offset.

	Userspace:
		- Linker must produce calls to the offsets described above.
		- Linker marks all sections relocatable with a base of 0.

	Kernelspace:
		- Go through each relocation with a base of 0 and create a new random
			base address.
		- Populate the SBT with the new base addresses.
		- Map the SBT where the binary wants it (should be just below the
			.text section and aligned to a page boundary).
		- Map the SBT read only as it is unchanged for static binaries (linker
			controls this but should have it read only).

	Assuming the .text section is position independent code, all processes that exec()
		this binary can share the .text and .rodata sections but have them located
		at different base offsets.

	Pros:
		- Eloquent, minimal changes to kernel.

	Cons:
		- Wasted space (~1 page in the virtual address space) as the SBT contains
			only a few entries. But overall this is negligible.
			GOT makes better use of the space but requires larger and more
			complex changes to the kernel to implement the same behaviour.
		- Requires changes to existing tooling.