1 | // Copyright 2019 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 MEMFD_LINUX |
16 | #define MEMFD_LINUX |
17 | |
18 | #include <cstddef> |
19 | |
20 | // Implementation of shared-memory regions backed by memfd_create(), which |
21 | // unfortunately is not exported by older GLibc versions, though it has been |
22 | // supported by the Linux kernel since 3.17 (good enough for Android and desktop |
23 | // Linux). |
24 | |
25 | class LinuxMemFd { |
26 | public: |
27 | LinuxMemFd() = default; |
28 | |
29 | LinuxMemFd(const char* name, size_t size) : LinuxMemFd() { |
30 | allocate(name, size); |
31 | } |
32 | |
33 | ~LinuxMemFd(); |
34 | |
35 | // Return true iff the region is valid/allocated. |
36 | bool isValid() const { return fd_ >= 0; } |
37 | |
38 | // Return region's internal file descriptor value. Useful for mapping. |
39 | int fd() const { return fd_; } |
40 | |
41 | // Set the internal handle to |fd|. |
42 | void importFd(int fd); |
43 | |
44 | // Return a copy of this instance's file descriptor (with CLO_EXEC set). |
45 | int exportFd() const; |
46 | |
47 | // Implement memfd_create() through direct syscalls if possible. |
48 | // On success, return true and sets |fd| accordingly. On failure, return |
49 | // false and sets errno. |
50 | bool allocate(const char* name, size_t size); |
51 | |
52 | // Map a segment of |size| bytes from |offset| from the region. |
53 | // Both |offset| and |size| should be page-aligned. Returns nullptr/errno |
54 | // on failure. |
55 | void* mapReadWrite(size_t offset, size_t size); |
56 | |
57 | // Unmap a region segment starting at |addr| of |size| bytes. |
58 | // Both |addr| and |size| should be page-aligned. Returns true on success |
59 | // or false/errno on failure. |
60 | bool unmap(void* addr, size_t size); |
61 | |
62 | void close(); |
63 | |
64 | private: |
65 | int fd_ = -1; |
66 | }; |
67 | |
68 | #endif // MEMFD_LINUX |
69 | |