1 // 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
15 #ifndef rr_ExecutableMemory_hpp
16 #define rr_ExecutableMemory_hpp
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstring>
21
22 namespace rr
23 {
24 size_t memoryPageSize();
25
26 void *allocateExecutable(size_t bytes); // Allocates memory that can be made executable using markExecutable()
27 void markExecutable(void *memory, size_t bytes);
28 void deallocateExecutable(void *memory, size_t bytes);
29
30 template<typename P>
unaligned_read(P * address)31 P unaligned_read(P *address)
32 {
33 P value;
34 memcpy(&value, address, sizeof(P));
35 return value;
36 }
37
38 template<typename P, typename V>
unaligned_write(P * address,V value)39 void unaligned_write(P *address, V value)
40 {
41 static_assert(sizeof(V) == sizeof(P), "value size must match pointee size");
42 memcpy(address, &value, sizeof(P));
43 }
44
45 template<typename P>
46 class unaligned_ref
47 {
48 public:
unaligned_ref(void * ptr)49 explicit unaligned_ref(void *ptr) : ptr((P*)ptr) {}
50
51 template<typename V>
operator =(V value)52 P operator=(V value)
53 {
54 unaligned_write(ptr, value);
55 return value;
56 }
57
operator P()58 operator P()
59 {
60 return unaligned_read((P*)ptr);
61 }
62
63 private:
64 P *ptr;
65 };
66
67 template<typename P>
68 class unaligned_ptr
69 {
70 template<typename S>
71 friend class unaligned_ptr;
72
73 public:
unaligned_ptr(P * ptr)74 unaligned_ptr(P *ptr) : ptr(ptr) {}
75
operator *()76 unaligned_ref<P> operator*()
77 {
78 return unaligned_ref<P>(ptr);
79 }
80
81 template<typename S>
operator S()82 operator S()
83 {
84 return S(ptr);
85 }
86
87 private:
88 void *ptr;
89 };
90 }
91
92 #endif // rr_ExecutableMemory_hpp
93