Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (C) 2008 Apple Inc. All rights reserved. |
michael@0 | 3 | * |
michael@0 | 4 | * Redistribution and use in source and binary forms, with or without |
michael@0 | 5 | * modification, are permitted provided that the following conditions |
michael@0 | 6 | * are met: |
michael@0 | 7 | * 1. Redistributions of source code must retain the above copyright |
michael@0 | 8 | * notice, this list of conditions and the following disclaimer. |
michael@0 | 9 | * 2. Redistributions in binary form must reproduce the above copyright |
michael@0 | 10 | * notice, this list of conditions and the following disclaimer in the |
michael@0 | 11 | * documentation and/or other materials provided with the distribution. |
michael@0 | 12 | * |
michael@0 | 13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
michael@0 | 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
michael@0 | 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
michael@0 | 16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
michael@0 | 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
michael@0 | 18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
michael@0 | 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
michael@0 | 20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
michael@0 | 21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
michael@0 | 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
michael@0 | 23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 24 | */ |
michael@0 | 25 | |
michael@0 | 26 | #include "assembler/jit/ExecutableAllocator.h" |
michael@0 | 27 | |
michael@0 | 28 | #if ENABLE_ASSEMBLER && WTF_OS_WINDOWS |
michael@0 | 29 | |
michael@0 | 30 | #include "jswin.h" |
michael@0 | 31 | #include "mozilla/WindowsVersion.h" |
michael@0 | 32 | |
michael@0 | 33 | extern uint64_t random_next(uint64_t *, int); |
michael@0 | 34 | |
michael@0 | 35 | namespace JSC { |
michael@0 | 36 | |
michael@0 | 37 | uint64_t ExecutableAllocator::rngSeed; |
michael@0 | 38 | |
michael@0 | 39 | size_t ExecutableAllocator::determinePageSize() |
michael@0 | 40 | { |
michael@0 | 41 | SYSTEM_INFO system_info; |
michael@0 | 42 | GetSystemInfo(&system_info); |
michael@0 | 43 | return system_info.dwPageSize; |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | void *ExecutableAllocator::computeRandomAllocationAddress() |
michael@0 | 47 | { |
michael@0 | 48 | /* |
michael@0 | 49 | * Inspiration is V8's OS::Allocate in platform-win32.cc. |
michael@0 | 50 | * |
michael@0 | 51 | * VirtualAlloc takes 64K chunks out of the virtual address space, so we |
michael@0 | 52 | * keep 16b alignment. |
michael@0 | 53 | * |
michael@0 | 54 | * x86: V8 comments say that keeping addresses in the [64MiB, 1GiB) range |
michael@0 | 55 | * tries to avoid system default DLL mapping space. In the end, we get 13 |
michael@0 | 56 | * bits of randomness in our selection. |
michael@0 | 57 | * x64: [2GiB, 4TiB), with 25 bits of randomness. |
michael@0 | 58 | */ |
michael@0 | 59 | static const unsigned chunkBits = 16; |
michael@0 | 60 | #if WTF_CPU_X86_64 |
michael@0 | 61 | static const uintptr_t base = 0x0000000080000000; |
michael@0 | 62 | static const uintptr_t mask = 0x000003ffffff0000; |
michael@0 | 63 | #elif WTF_CPU_X86 |
michael@0 | 64 | static const uintptr_t base = 0x04000000; |
michael@0 | 65 | static const uintptr_t mask = 0x3fff0000; |
michael@0 | 66 | #else |
michael@0 | 67 | # error "Unsupported architecture" |
michael@0 | 68 | #endif |
michael@0 | 69 | uint64_t rand = random_next(&rngSeed, 32) << chunkBits; |
michael@0 | 70 | return (void *) (base | rand & mask); |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | static bool |
michael@0 | 74 | RandomizeIsBrokenImpl() |
michael@0 | 75 | { |
michael@0 | 76 | // We disable everything before Vista, for now. |
michael@0 | 77 | return !mozilla::IsVistaOrLater(); |
michael@0 | 78 | } |
michael@0 | 79 | |
michael@0 | 80 | static bool |
michael@0 | 81 | RandomizeIsBroken() |
michael@0 | 82 | { |
michael@0 | 83 | // Use the compiler's intrinsic guards for |static type value = expr| to avoid some potential |
michael@0 | 84 | // races if runtimes are created from multiple threads. |
michael@0 | 85 | static int result = RandomizeIsBrokenImpl(); |
michael@0 | 86 | return !!result; |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) |
michael@0 | 90 | { |
michael@0 | 91 | void *allocation = NULL; |
michael@0 | 92 | // Randomization disabled to avoid a performance fault on x64 builds. |
michael@0 | 93 | // See bug 728623. |
michael@0 | 94 | #ifndef JS_CPU_X64 |
michael@0 | 95 | if (!RandomizeIsBroken()) { |
michael@0 | 96 | void *randomAddress = computeRandomAllocationAddress(); |
michael@0 | 97 | allocation = VirtualAlloc(randomAddress, n, MEM_COMMIT | MEM_RESERVE, |
michael@0 | 98 | PAGE_EXECUTE_READWRITE); |
michael@0 | 99 | } |
michael@0 | 100 | #endif |
michael@0 | 101 | if (!allocation) |
michael@0 | 102 | allocation = VirtualAlloc(0, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); |
michael@0 | 103 | ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n }; |
michael@0 | 104 | return alloc; |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) |
michael@0 | 108 | { |
michael@0 | 109 | VirtualFree(alloc.pages, 0, MEM_RELEASE); |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | void |
michael@0 | 113 | ExecutablePool::toggleAllCodeAsAccessible(bool accessible) |
michael@0 | 114 | { |
michael@0 | 115 | char* begin = m_allocation.pages; |
michael@0 | 116 | size_t size = m_freePtr - begin; |
michael@0 | 117 | |
michael@0 | 118 | if (size) { |
michael@0 | 119 | // N.B. DEP is not on automatically in Windows XP, so be sure to use |
michael@0 | 120 | // PAGE_NOACCESS instead of PAGE_READWRITE when making inaccessible. |
michael@0 | 121 | DWORD oldProtect; |
michael@0 | 122 | int flags = accessible ? PAGE_EXECUTE_READWRITE : PAGE_NOACCESS; |
michael@0 | 123 | if (!VirtualProtect(begin, size, flags, &oldProtect)) |
michael@0 | 124 | MOZ_CRASH(); |
michael@0 | 125 | } |
michael@0 | 126 | } |
michael@0 | 127 | |
michael@0 | 128 | #if ENABLE_ASSEMBLER_WX_EXCLUSIVE |
michael@0 | 129 | #error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform." |
michael@0 | 130 | #endif |
michael@0 | 131 | |
michael@0 | 132 | } |
michael@0 | 133 | |
michael@0 | 134 | #endif // HAVE(ASSEMBLER) |