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