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
25class LinuxMemFd {
26public:
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
64private:
65 int fd_ = -1;
66};
67
68#endif // MEMFD_LINUX
69