1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#ifndef MASM_EXECUTABLEALLOCATOR_H
4#define MASM_EXECUTABLEALLOCATOR_H
5
6#include <RefPtr.h>
7#include <RefCounted.h>
8#include <wtf/PageBlock.h>
9
10#include <private/qv4executableallocator_p.h>
11
12#if OS(INTEGRITY)
13#include "OSAllocator.h"
14#endif
15
16#if OS(WINDOWS)
17#include <qt_windows.h>
18#else
19#include <sys/mman.h>
20#include <unistd.h>
21#endif
22
23#ifdef __QNXNTO__
24using std::perror;
25#endif
26
27namespace JSC {
28
29class JSGlobalData;
30
31struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> {
32 ExecutableMemoryHandle(QV4::ExecutableAllocator *allocator, size_t size)
33 : m_allocator(allocator)
34 , m_size(size)
35 {
36 m_allocation = allocator->allocate(size);
37 }
38 ~ExecutableMemoryHandle()
39 {
40 m_allocation->deallocate(allocator: m_allocator);
41 }
42
43 inline void shrink(size_t) {
44 // ### TODO.
45 }
46
47 inline bool isManaged() const { return true; }
48
49 void *memoryStart() { return m_allocation->memoryStart(); }
50 size_t memorySize() { return m_allocation->memorySize(); }
51
52 void *exceptionHandlerStart() { return m_allocation->exceptionHandlerStart(); }
53 size_t exceptionHandlerSize() { return m_allocation->exceptionHandlerSize(); }
54
55 void *codeStart() { return m_allocation->codeStart(); }
56 size_t codeSize() { return m_size; }
57
58 QV4::ExecutableAllocator::ChunkOfPages *chunk() const
59 { return m_allocator->chunkForAllocation(allocation: m_allocation); }
60
61 QV4::ExecutableAllocator *m_allocator;
62 QV4::ExecutableAllocator::Allocation *m_allocation;
63 size_t m_size;
64};
65
66struct ExecutableAllocator {
67 ExecutableAllocator(QV4::ExecutableAllocator *alloc)
68 : realAllocator(alloc)
69 {}
70
71 Ref<ExecutableMemoryHandle> allocate(JSGlobalData&, size_t size, void*, int)
72 {
73 return adoptRef(ptr: new ExecutableMemoryHandle(realAllocator, size));
74 }
75
76 static bool makeWritable(void* addr, size_t size)
77 {
78 quintptr pageSize = WTF::pageSize();
79 quintptr iaddr = reinterpret_cast<quintptr>(addr);
80 quintptr roundAddr = iaddr & ~(pageSize - 1);
81 size = size + (iaddr - roundAddr);
82 addr = reinterpret_cast<void*>(roundAddr);
83
84#if ENABLE(ASSEMBLER_WX_EXCLUSIVE) && !defined(V4_BOOTSTRAP)
85# if OS(WINDOWS)
86 DWORD oldProtect;
87# if !OS(WINRT)
88 VirtualProtect(addr, size, PAGE_READWRITE, &oldProtect);
89# else
90 bool hr = VirtualProtectFromApp(addr, size, PAGE_READWRITE, &oldProtect);
91 if (!hr) {
92 return false;
93 }
94# endif
95# elif OS(INTEGRITY)
96 OSAllocator::setMemoryAttributes(addr, size, /*writable*/ true, /*executable*/ false);
97# else
98 int mode = PROT_READ | PROT_WRITE;
99 if (mprotect(addr: addr, len: size, prot: mode) != 0) {
100 perror(s: "mprotect failed in ExecutableAllocator::makeWritable");
101 return false;
102 }
103# endif
104#else
105 // We assume we already have RWX
106 (void)addr; // suppress unused parameter warning
107 (void)size; // suppress unused parameter warning
108#endif
109 return true;
110 }
111
112 static bool makeExecutable(void* addr, size_t size)
113 {
114 quintptr pageSize = WTF::pageSize();
115 quintptr iaddr = reinterpret_cast<quintptr>(addr);
116 quintptr roundAddr = iaddr & ~(pageSize - 1);
117 size = size + (iaddr - roundAddr);
118 addr = reinterpret_cast<void*>(roundAddr);
119
120#if !defined(V4_BOOTSTRAP)
121#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
122# if OS(WINDOWS)
123 DWORD oldProtect;
124# if !OS(WINRT)
125 VirtualProtect(addr, size, PAGE_EXECUTE_READ, &oldProtect);
126# else
127 bool hr = VirtualProtectFromApp(addr, size, PAGE_EXECUTE_READ, &oldProtect);
128 if (!hr) {
129 return false;
130 }
131# endif
132# elif OS(INTEGRITY)
133 OSAllocator::setMemoryAttributes(addr, size, /*writable*/ false, /*executable*/ true);
134# else
135 int mode = PROT_READ | PROT_EXEC;
136 if (mprotect(addr: addr, len: size, prot: mode) != 0) {
137 perror(s: "mprotect failed in ExecutableAllocator::makeExecutable");
138 return false;
139 }
140# endif
141#else
142# error "Only W^X is supported"
143#endif
144#else
145 (void)addr; // suppress unused parameter warning
146 (void)size; // suppress unused parameter warning
147#endif
148 return true;
149 }
150
151 QV4::ExecutableAllocator *realAllocator;
152};
153
154}
155
156#endif // MASM_EXECUTABLEALLOCATOR_H
157

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtdeclarative/src/3rdparty/masm/stubs/ExecutableAllocator.h