| 32 | } |
| 33 | |
| 34 | void ProtectMemory(void* addr, const size_t length, const EProtectMemory mode) { |
| 35 | Y_ABORT_UNLESS(!(mode & ~(PM_READ | PM_WRITE | PM_EXEC)), "Invalid memory protection flag combination. "); |
| 36 | |
| 37 | #if defined(_unix_) || defined(_darwin_) |
| 38 | int mpMode = PROT_NONE; |
| 39 | if (mode & PM_READ) { |
| 40 | mpMode |= PROT_READ; |
| 41 | } |
| 42 | if (mode & PM_WRITE) { |
| 43 | mpMode |= PROT_WRITE; |
| 44 | } |
| 45 | if (mode & PM_EXEC) { |
| 46 | mpMode |= PROT_EXEC; |
| 47 | } |
| 48 | // some old manpages for mprotect say 'const void* addr', but that's wrong |
| 49 | if (mprotect(addr, length, mpMode) == -1) { |
| 50 | ythrow TSystemError() << "Memory protection failed for mode " << ModeToString(mode) << ". "; |
| 51 | } |
| 52 | #endif |
| 53 | |
| 54 | #ifdef _win_ |
| 55 | DWORD mpMode = PAGE_NOACCESS; |
| 56 | // windows developers are not aware of bit flags :( |
| 57 | |
| 58 | /* |
| 59 | * It's unclear that we should NOT fail on Windows that does not support write-only |
| 60 | * memory protection. As we don't know, what behavior is more correct, we choose |
| 61 | * one of them. A discussion was here: REVIEW: 39725 |
| 62 | */ |
| 63 | switch (mode.ToBaseType()) { |
| 64 | case PM_READ: |
| 65 | mpMode = PAGE_READONLY; |
| 66 | break; |
| 67 | case PM_WRITE: |
| 68 | mpMode = PAGE_READWRITE; |
| 69 | break; // BUG: no write-only support |
| 70 | /*case PM_WRITE: |
| 71 | ythrow TSystemError() << "Write-only protection mode is not supported under Windows. ";*/ |
| 72 | case PM_READ | PM_WRITE: |
| 73 | mpMode = PAGE_READWRITE; |
| 74 | break; |
| 75 | case PM_EXEC: |
| 76 | mpMode = PAGE_EXECUTE; |
| 77 | break; |
| 78 | case PM_READ | PM_EXEC: |
| 79 | mpMode = PAGE_EXECUTE_READ; |
| 80 | break; |
| 81 | case PM_WRITE | PM_EXEC: |
| 82 | mpMode = PAGE_EXECUTE_READWRITE; |
| 83 | break; // BUG: no write-only support |
| 84 | /*case PM_WRITE | PM_EXEC: |
| 85 | ythrow TSystemError() << "Write-execute-only protection mode is not supported under Windows. ";*/ |
| 86 | case PM_READ | PM_WRITE | PM_EXEC: |
| 87 | mpMode = PAGE_EXECUTE_READWRITE; |
| 88 | break; |
| 89 | } |
| 90 | DWORD oldMode = 0; |
| 91 | if (!VirtualProtect(addr, length, mpMode, &oldMode)) { |
no test coverage detected