blob: dbbe32aa50f9b1e465fa95ccebe6151b898ea325 [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
Ben Clayton713b8d32019-12-17 20:37:56 +000026enum MemoryPermission
27{
Sergey Ulanovebb0bec2019-12-12 11:53:04 -080028 PERMISSION_READ = 1,
29 PERMISSION_WRITE = 2,
30 PERMISSION_EXECUTE = 4,
31};
32
33// Allocates memory with the specified permissions. If |need_exec| is true then
34// the allocate memory can be made marked executable using protectMemoryPages().
Ben Clayton713b8d32019-12-17 20:37:56 +000035void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec);
Sergey Ulanovebb0bec2019-12-12 11:53:04 -080036
37// Sets permissions for memory allocated with allocateMemoryPages().
38void protectMemoryPages(void *memory, size_t bytes, int permissions);
39
40// Releases memory allocated with allocateMemoryPages().
41void deallocateMemoryPages(void *memory, size_t bytes);
Nicolas Capens8d2cf752018-11-22 11:13:45 -050042
43template<typename P>
44P unaligned_read(P *address)
45{
46 P value;
47 memcpy(&value, address, sizeof(P));
48 return value;
49}
50
51template<typename P, typename V>
52void unaligned_write(P *address, V value)
53{
54 static_assert(sizeof(V) == sizeof(P), "value size must match pointee size");
55 memcpy(address, &value, sizeof(P));
56}
57
58template<typename P>
59class unaligned_ref
60{
61public:
Ben Clayton713b8d32019-12-17 20:37:56 +000062 explicit unaligned_ref(void *ptr)
63 : ptr((P *)ptr)
64 {}
Nicolas Capens8d2cf752018-11-22 11:13:45 -050065
66 template<typename V>
67 P operator=(V value)
68 {
69 unaligned_write(ptr, value);
70 return value;
71 }
72
73 operator P()
74 {
Ben Clayton713b8d32019-12-17 20:37:56 +000075 return unaligned_read((P *)ptr);
Nicolas Capens8d2cf752018-11-22 11:13:45 -050076 }
77
78private:
79 P *ptr;
80};
81
82template<typename P>
83class unaligned_ptr
84{
85 template<typename S>
86 friend class unaligned_ptr;
87
88public:
Ben Clayton713b8d32019-12-17 20:37:56 +000089 unaligned_ptr(P *ptr)
90 : ptr(ptr)
91 {}
Nicolas Capens8d2cf752018-11-22 11:13:45 -050092
93 unaligned_ref<P> operator*()
94 {
95 return unaligned_ref<P>(ptr);
96 }
97
98 template<typename S>
99 operator S()
100 {
101 return S(ptr);
102 }
103
104private:
105 void *ptr;
106};
Nicolas Capens157ba262019-12-10 17:49:14 -0500107
108} // namespace rr
Nicolas Capensc07dc4b2018-08-06 14:20:45 -0400109
Ben Clayton713b8d32019-12-17 20:37:56 +0000110#endif // rr_ExecutableMemory_hpp