Splits the VMM-managed memory into two pieces: "vmcode" which is guaranteed 32-bit-displacement-reachable, and "vmheap" which has no such guarantees.
Adds a new option -vmheap_size to control the size of vmheap. The placement is left to the OS, rather than DR trying to do ASLR, as modern OS's have their own ASLR.
Changes which_vmm_t to a bitmask and adds a flag VMM_REACHABLE so callers can specify which region to use. Adds the flag to all appropriate call sites.
Implements the -reachable_heap option: when on, only vmcode is used and there is no 2nd region.
Adds heap_reachable_{alloc,free} and use for dr_{global,thread}_{alloc,free}. Adds local and global reachable heap units to implement this. Adds storage of the type of heap inside thread_units_t and heap_unit_t. Places both types of units on the same free lists, but checks for a match before re-using. Explicitly exercises each heap's lock at init time to avoid shutdown issues due to the temp heapmgt copy.
Changes the heap used by the trace buffer, private instr encode, and allocated instr raw bits to use reachable heap to avoid rip-relative re-relativization problems.
Refactors heap code to work with multiple regions, either by taking in the vm_heap_t or switching to routines that do not require it (such as s/vmm_is_reserved_unit/is_vmm_reserved_address/).
Refactors other core code to handle multiple regions. Adds iterate_vmm_regions() for running code for each region; changes memquery_emulate's probe code to query every time instead of trying to cache one region's bounds.
Implements the API flag DR_ALLOC_CACHE_REACHABLE to actually split into reachable and non-reachable memory. As promised, dr_nonheap_alloc() and dr_{global,thread}_alloc() are reachable.
Requires -reachable_heap for -heap_in_lower_4GB as otherwise there is not enough room on Linux, since we use MAP_32BIT which really means the lower 2GB. Updates relevant tests to pass both.
Fixes #1132 (closed)