blob: b0ca05e243ae7dbc69b2423e82bc5850f1a7196a [file] [log] [blame]
Nicolas Capensc07dc4b2018-08-06 14:20:45 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Nicolas Capens1a3ce872018-10-10 10:42:36 -040015#ifndef rr_ExecutableMemory_hpp
16#define rr_ExecutableMemory_hpp
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040017
Nicolas Capens8d2cf752018-11-22 11:13:45 -050018#include <cstddef>
19#include <cstdint>
20#include <cstring>
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040021
Nicolas Capens157ba262019-12-10 17:49:14 -050022namespace rr {
23
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040024size_t memoryPageSize();
25
Sergey Ulanovebb0bec2019-12-12 11:53:04 -080026enum MemoryPermission {
27 PERMISSION_READ = 1,
28 PERMISSION_WRITE = 2,
29 PERMISSION_EXECUTE = 4,
30};
31
32// Allocates memory with the specified permissions. If |need_exec| is true then
33// the allocate memory can be made marked executable using protectMemoryPages().
34void* allocateMemoryPages(size_t bytes, int permissions, bool need_exec);
35
36// Sets permissions for memory allocated with allocateMemoryPages().
37void protectMemoryPages(void *memory, size_t bytes, int permissions);
38
39// Releases memory allocated with allocateMemoryPages().
40void deallocateMemoryPages(void *memory, size_t bytes);
Nicolas Capens8d2cf752018-11-22 11:13:45 -050041
42template<typename P>
43P unaligned_read(P *address)
44{
45 P value;
46 memcpy(&value, address, sizeof(P));
47 return value;
48}
49
50template<typename P, typename V>
51void unaligned_write(P *address, V value)
52{
53 static_assert(sizeof(V) == sizeof(P), "value size must match pointee size");
54 memcpy(address, &value, sizeof(P));
55}
56
57template<typename P>
58class unaligned_ref
59{
60public:
61 explicit unaligned_ref(void *ptr) : ptr((P*)ptr) {}
62
63 template<typename V>
64 P operator=(V value)
65 {
66 unaligned_write(ptr, value);
67 return value;
68 }
69
70 operator P()
71 {
72 return unaligned_read((P*)ptr);
73 }
74
75private:
76 P *ptr;
77};
78
79template<typename P>
80class unaligned_ptr
81{
82 template<typename S>
83 friend class unaligned_ptr;
84
85public:
86 unaligned_ptr(P *ptr) : ptr(ptr) {}
87
88 unaligned_ref<P> operator*()
89 {
90 return unaligned_ref<P>(ptr);
91 }
92
93 template<typename S>
94 operator S()
95 {
96 return S(ptr);
97 }
98
99private:
100 void *ptr;
101};
Nicolas Capens157ba262019-12-10 17:49:14 -0500102
103} // namespace rr
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400104
Nicolas Capens1a3ce872018-10-10 10:42:36 -0400105#endif // rr_ExecutableMemory_hpp