Make CoreCLR work properly under PaX's RANDMMAP (#11382)
authorKoundinya Veluri <kouvel@microsoft.com>
Mon, 8 May 2017 19:16:21 +0000 (12:16 -0700)
committerGitHub <noreply@github.com>
Mon, 8 May 2017 19:16:21 +0000 (12:16 -0700)
commit8514226271bd125d62fbab552d9ebb107bd67fb1
treeddf68784978643588b40e680478cdd00ecb184c0
parent1db5bbc0b29c2801a2d548ee852424d6ea207388
Make CoreCLR work properly under PaX's RANDMMAP (#11382)

Make CoreCLR work properly under PaX's RANDMMAP

Issues:
- The ExecutableMemoryAllocator is used to attempt to map native images into a memory range near libcoreclr so that its helper table can use short relative addresses for jumps to libcoreclr
  - RANDMMAP typically prevents mmap calls with a specific address from reserving memory at the requested address, so the executable memory allocator fails to reserve any memory. When Server GC is enabled, the large GC heap can exacerbate the issue by taking address space near libcoreclr.
- Native images are loaded far from libcoreclr, and now jump stub space needs to be allocated near the native image, but RANDMMAP typically prevents this too
- NGenReserveForJumpStubs is intended to reserve some memory near mapped native images for jump stubs, but that reservation is done with a separate mmap call in the same way as above and RANDMMAP typically prevents this too
- The JIT needs to allocate memory for code that may need to jump/call to a native image or libcoreclr, which may require jump stubs near the code that cannot be allocated. CodeHeapReserveForJumpStubs reserves space in code heap blocks without using a separate call to mmap, so this works, but without this environment variable by default there is still a good chance of failing.
- See https://github.com/dotnet/coreclr/blob/56d550d4f8aec2dd40b72a182205d0a2463a1bc9/Documentation/design-docs/jump-stubs.md for more details

Fixes #8480
- It would be ideal to fix all of the above properly, such that there would never be a need to attempt reserving memory within a certain range. Since we're running out of time for 2.0, I figured the following simpler, temporary solution that should cover most of the practical cases, may be appropriate for 2.0.
- Extended ExecutableMemoryAllocator to reserve address space even when it cannot do so near libcoreclr
- Had ClrVirtualAllocWithinRange use the executable memory allocator to reserve memory for jump stubs when the requested range is satisfied
- This covers a maximum of ~2 GB of executable code and should cover most of the practical cases. Once this space is exhausted, under RANDMMAP, native images loaded later will fail, and for jitted code the environment variable above can be used.
src/dlls/mscordac/mscordac_unixexports.src
src/pal/inc/pal.h
src/pal/src/include/pal/virtual.h
src/pal/src/map/map.cpp
src/pal/src/map/virtual.cpp
src/utilcode/util.cpp