| 46 | } |
| 47 | |
| 48 | void* X86GeneratedCode::AllocateGuestCodeSpace(size_t Size) { |
| 49 | #ifndef _WIN32 |
| 50 | FEX_CONFIG_OPT(Is64BitMode, IS64BIT_MODE); |
| 51 | |
| 52 | if (Is64BitMode()) { |
| 53 | // 64bit mode can have its sigret handler anywhere |
| 54 | return FEXCore::Allocator::VirtualAlloc(Size); |
| 55 | } |
| 56 | |
| 57 | // First 64bit page |
| 58 | constexpr uintptr_t LOCATION_MAX = 0x1'0000'0000; |
| 59 | |
| 60 | // 32bit mode |
| 61 | // We need to have the sigret handler in the lower 32bits of memory space |
| 62 | // Scan top down and try to allocate a location |
| 63 | for (size_t Location = 0xFFFF'E000; Location != 0x0; Location -= 0x1000) { |
| 64 | void* Ptr = ::mmap(reinterpret_cast<void*>(Location), Size, PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
| 65 | |
| 66 | if (Ptr != MAP_FAILED && reinterpret_cast<uintptr_t>(Ptr) >= LOCATION_MAX) { |
| 67 | // Failed to map in the lower 32bits |
| 68 | // Try again |
| 69 | // Can happen in the case that host kernel ignores MAP_FIXED_NOREPLACE |
| 70 | ::munmap(Ptr, Size); |
| 71 | continue; |
| 72 | } |
| 73 | |
| 74 | if (Ptr != MAP_FAILED) { |
| 75 | return Ptr; |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | // Can't do anything about this |
| 80 | // Here's hoping the application doesn't use signals |
| 81 | return MAP_FAILED; |
| 82 | #else |
| 83 | return nullptr; |
| 84 | #endif |
| 85 | } |
| 86 | |
| 87 | } // namespace FEXCore |
nothing calls this directly
no test coverage detected