Skip to content

Commit 1b905dc

Browse files
committed
add explicit types for mmap() flags
1 parent 37a708b commit 1b905dc

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

api/sys/mman.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* provides namespaced types for `sys_mman(0p)` values
3+
*/
4+
#ifndef _SYS_MMAN_HPP
5+
#define _SYS_MMAN_HPP
6+
7+
#include <cstdint>
8+
#include <sys/mman.h>
9+
#include <util/bitops.hpp>
10+
#include <type_traits>
11+
12+
namespace os::mem {
13+
enum class Flags : uint8_t {
14+
None = 0,
15+
Shared = MAP_SHARED,
16+
Private = MAP_PRIVATE,
17+
Fixed = MAP_FIXED,
18+
Anonymous = MAP_ANONYMOUS,
19+
};
20+
} // os::mmap
21+
22+
23+
namespace util {
24+
inline namespace bitops {
25+
template<> struct enable_bitmask_ops<os::mem::Flags> {
26+
using type = std::underlying_type<os::mem::Flags>::type;
27+
static constexpr bool enable = true;
28+
};
29+
}
30+

api/util/bitops.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,34 @@ constexpr operator~(E flag){
115115

116116
// bool has_flag(flag)
117117
template<typename E>
118-
constexpr typename std::enable_if<enable_bitmask_ops<E>::enable, bool>::type
118+
[[nodiscard]] constexpr typename std::enable_if<enable_bitmask_ops<E>::enable, bool>::type
119119
has_flag(E flag){
120120
using base_type = typename std::underlying_type<E>::type;
121121
return static_cast<base_type>(flag);
122122
}
123123

124124
// bool has_flag(field, flags)
125125
template<typename E>
126-
constexpr typename std::enable_if<enable_bitmask_ops<E>::enable, bool>::type
126+
[[nodiscard]] constexpr typename std::enable_if<enable_bitmask_ops<E>::enable, bool>::type
127127
has_flag(E field, E flags){
128128
return (field & flags) == flags ;
129129
}
130130

131+
// bool missing_flag(flag)
132+
template<typename E>
133+
[[nodiscard]] constexpr typename std::enable_if<enable_bitmask_ops<E>::enable, bool>::type
134+
missing_flag(E flag){
135+
using base_type = typename std::underlying_type<E>::type;
136+
return static_cast<base_type>(flag) == 0;
137+
}
138+
139+
// bool missing_flag(field, flags)
140+
template<typename E>
141+
[[nodiscard]] constexpr typename std::enable_if<enable_bitmask_ops<E>::enable, bool>::type
142+
missing_flag(E field, E flags) noexcept {
143+
return (field & flags) != flags;
144+
}
145+
131146

132147
// Enable for uint8_t
133148
template<>

src/musl/mmap.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "common.hpp"
22
#include <cstdint>
3-
#include <sys/mman.h>
3+
#include <sys/mman.hpp>
44
#include <errno.h>
55
#include <util/alloc_buddy.hpp>
66
#include <os>
@@ -54,9 +54,11 @@ uintptr_t mmap_allocation_end() {
5454
return alloc->highest_used();
5555
}
5656

57-
static void* sys_mmap(void * addr, size_t length, int /*prot*/, int flags,
57+
static void* sys_mmap(void * addr, size_t length, int /*prot*/, int _flags,
5858
int fd, off_t /*offset*/)
5959
{
60+
using os::mmap::Flags;
61+
const Flags flags = static_cast<Flags>(_flags);
6062

6163
// TODO: Implement minimal functionality to be POSIX compliant
6264
// https://pubs.opengroup.org/onlinepubs/009695399/functions/mmap.html
@@ -68,37 +70,38 @@ static void* sys_mmap(void * addr, size_t length, int /*prot*/, int flags,
6870
return MAP_FAILED;
6971
}
7072

71-
if ((flags & MAP_ANONYMOUS) == 0) {
73+
if (util::missing_flag(flags, Flags::Anonymous)) {
7274
Expects(false && "We only support MAP_ANONYMOUS calls to mmap()");
7375
errno = ENOTSUP;
7476
return MAP_FAILED;
7577
}
7678

77-
if ((flags & MAP_FIXED) > 0) {
79+
if (util::has_flag(flags, Flags::Fixed)) {
7880
Expects(false && "MAP_FIXED not supported.");
7981
errno = ENOTSUP;
8082
return MAP_FAILED;
8183
}
8284

83-
if (((flags & MAP_PRIVATE) > 0) && ((flags & MAP_ANONYMOUS) == 0)) {
84-
Expects(false && "MAP_PRIVATE only supported for MAP_ANONYMOUS");
85+
if (util::has_flag(flags, Flags::Private) && util::missing_flag(flags, Flags::Anonymous)) {
86+
Expects(false && "MAP_PRIVATE only supported for MAP_ANONYMOS");
8587
errno = ENOTSUP;
8688
return MAP_FAILED;
8789
}
8890

89-
if (((flags & MAP_PRIVATE) > 0) && (addr != 0)) {
91+
if (util::has_flag(flags, Flags::Private) && (addr != 0)) {
9092
Expects(false && "MAP_PRIVATE only supported for new allocations (address=0).");
9193
errno = ENOTSUP;
9294
return MAP_FAILED;
9395
}
9496

95-
if (((flags & MAP_SHARED) == 0) && ((flags & MAP_PRIVATE) == 0)) {
97+
if (util::missing_flag(flags, Flags::Shared) && util::missing_flag(flags, Flags::Private)) {
9698
Expects(false && "MAP_SHARED or MAP_PRIVATE must be set.");
9799
errno = ENOTSUP;
98100
return MAP_FAILED;
99101
}
100102

101103
// If we get here, the following should be true:
104+
//
102105
// MAP_ANONYMOUS set + MAP_SHARED or MAP_PRIVATE
103106
// fd should be 0, address should be 0 for MAP_PRIVATE
104107
// (address is in any case ignored)

0 commit comments

Comments
 (0)