1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/assembler/jit/ExecutableAllocatorPosix.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,113 @@ 1.4 +/* 1.5 + * Copyright (C) 2008 Apple Inc. All rights reserved. 1.6 + * 1.7 + * Redistribution and use in source and binary forms, with or without 1.8 + * modification, are permitted provided that the following conditions 1.9 + * are met: 1.10 + * 1. Redistributions of source code must retain the above copyright 1.11 + * notice, this list of conditions and the following disclaimer. 1.12 + * 2. Redistributions in binary form must reproduce the above copyright 1.13 + * notice, this list of conditions and the following disclaimer in the 1.14 + * documentation and/or other materials provided with the distribution. 1.15 + * 1.16 + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 1.17 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.18 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1.19 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 1.20 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1.21 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1.22 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 1.23 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 1.24 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.25 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.27 + */ 1.28 + 1.29 +#include "assembler/jit/ExecutableAllocator.h" 1.30 + 1.31 +#if ENABLE_ASSEMBLER && WTF_OS_UNIX && !WTF_OS_SYMBIAN 1.32 + 1.33 +#include <sys/mman.h> 1.34 +#include <unistd.h> 1.35 + 1.36 +#include "assembler/wtf/Assertions.h" 1.37 +#include "assembler/wtf/VMTags.h" 1.38 +#include "js/Utility.h" 1.39 + 1.40 +namespace JSC { 1.41 + 1.42 +size_t ExecutableAllocator::determinePageSize() 1.43 +{ 1.44 + return getpagesize(); 1.45 +} 1.46 + 1.47 +ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) 1.48 +{ 1.49 + void *allocation = mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0); 1.50 + if (allocation == MAP_FAILED) 1.51 + allocation = NULL; 1.52 + ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n }; 1.53 + return alloc; 1.54 +} 1.55 + 1.56 +void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) 1.57 +{ 1.58 + int result = munmap(alloc.pages, alloc.size); 1.59 + ASSERT_UNUSED(result, !result); 1.60 +} 1.61 + 1.62 +#if WTF_ENABLE_ASSEMBLER_WX_EXCLUSIVE 1.63 +void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting setting) 1.64 +{ 1.65 + if (!pageSize) 1.66 + intializePageSize(); 1.67 + 1.68 + // Calculate the start of the page containing this region, 1.69 + // and account for this extra memory within size. 1.70 + intptr_t startPtr = reinterpret_cast<intptr_t>(start); 1.71 + intptr_t pageStartPtr = startPtr & ~(pageSize - 1); 1.72 + void* pageStart = reinterpret_cast<void*>(pageStartPtr); 1.73 + size += (startPtr - pageStartPtr); 1.74 + 1.75 + // Round size up 1.76 + size += (pageSize - 1); 1.77 + size &= ~(pageSize - 1); 1.78 + 1.79 + mprotect(pageStart, size, (setting == Writable) ? PROTECTION_FLAGS_RW : PROTECTION_FLAGS_RX); 1.80 +} 1.81 +#endif 1.82 + 1.83 +#if WTF_CPU_ARM_TRADITIONAL && WTF_OS_LINUX && WTF_COMPILER_RVCT 1.84 +__asm void ExecutableAllocator::cacheFlush(void* code, size_t size) 1.85 +{ 1.86 + ARM 1.87 + push {r7} 1.88 + add r1, r1, r0 1.89 + mov r7, #0xf0000 1.90 + add r7, r7, #0x2 1.91 + mov r2, #0x0 1.92 + svc #0x0 1.93 + pop {r7} 1.94 + bx lr 1.95 +} 1.96 +#endif 1.97 + 1.98 +void 1.99 +ExecutablePool::toggleAllCodeAsAccessible(bool accessible) 1.100 +{ 1.101 + char* begin = m_allocation.pages; 1.102 + size_t size = m_freePtr - begin; 1.103 + 1.104 + if (size) { 1.105 + // N.B. Some systems, like 32bit Mac OS 10.6, implicitly add PROT_EXEC 1.106 + // when mprotect'ing memory with any flag other than PROT_NONE. Be 1.107 + // sure to use PROT_NONE when making inaccessible. 1.108 + int flags = accessible ? PROT_READ | PROT_WRITE | PROT_EXEC : PROT_NONE; 1.109 + if (mprotect(begin, size, flags)) 1.110 + MOZ_CRASH(); 1.111 + } 1.112 +} 1.113 + 1.114 +} 1.115 + 1.116 +#endif // HAVE(ASSEMBLER)