Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/lib/system/mmap.cpp
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
4
#include "system/mmap.h"
5
6
#include "common/config.h"
7
#include "common/defines.h"
8
9
#include <cstdint>
10
#include <memory>
11
#include <utility>
12
13
#ifdef HAVE_MMAP
14
#include <fcntl.h>
15
#include <sys/mman.h>
16
#include <sys/stat.h>
17
#include <unistd.h>
18
#elif WASMEDGE_OS_WINDOWS
19
#include "system/winapi.h"
20
#endif
21
22
namespace WasmEdge {
23
24
namespace {
25
#ifdef HAVE_MMAP
26
static inline bool kSupported = true;
27
struct Implement {
28
  void *Address = MAP_FAILED;
29
  int File = -1;
30
  uint64_t Size = 0;
31
0
  Implement(const std::filesystem::path &Path) noexcept {
32
0
    File = open(Path.native().c_str(), O_RDONLY);
33
0
    if (File < 0) {
34
0
      return;
35
0
    }
36
37
0
    {
38
0
      struct stat Stat;
39
0
      if (fstat(File, &Stat) < 0) {
40
0
        return;
41
0
      }
42
0
      Size = Stat.st_size;
43
0
    }
44
45
0
    Address = mmap(nullptr, Size, PROT_READ, MAP_SHARED, File, 0);
46
0
  }
47
0
  ~Implement() noexcept {
48
0
    if (Address != MAP_FAILED) {
49
0
      munmap(Address, Size);
50
0
    }
51
0
    if (File >= 0) {
52
0
      close(File);
53
0
    }
54
0
  }
55
0
  bool ok() const noexcept { return Address != MAP_FAILED; }
56
};
57
#elif WASMEDGE_OS_WINDOWS
58
static inline bool kSupported = true;
59
struct Implement {
60
  void *Address = nullptr;
61
  winapi::HANDLE_ File = nullptr;
62
  winapi::HANDLE_ Map = nullptr;
63
  Implement(const std::filesystem::path &Path) noexcept {
64
65
#if NTDDI_VERSION >= NTDDI_WIN8
66
    winapi::CREATEFILE2_EXTENDED_PARAMETERS_ Create2ExParams;
67
    Create2ExParams.dwSize = sizeof(Create2ExParams);
68
    Create2ExParams.dwFileAttributes = 0;
69
    Create2ExParams.dwFileFlags = winapi::FILE_FLAG_SEQUENTIAL_SCAN_;
70
    Create2ExParams.dwSecurityQosFlags = 0;
71
    Create2ExParams.lpSecurityAttributes = nullptr;
72
    Create2ExParams.hTemplateFile = nullptr;
73
74
    File = winapi::CreateFile2(Path.c_str(), winapi::GENERIC_READ_,
75
                               winapi::FILE_SHARE_VALID_FLAGS_,
76
                               winapi::OPEN_EXISTING_, &Create2ExParams);
77
#else
78
    File = winapi::CreateFileW(Path.c_str(), winapi::GENERIC_READ_,
79
                               winapi::FILE_SHARE_VALID_FLAGS_, nullptr,
80
                               winapi::OPEN_EXISTING_,
81
                               winapi::FILE_FLAG_SEQUENTIAL_SCAN_, nullptr);
82
#endif
83
    if (File == winapi::INVALID_HANDLE_VALUE_) {
84
      File = nullptr;
85
      return;
86
    }
87
88
    winapi::LARGE_INTEGER_ Size;
89
    winapi::GetFileSizeEx(File, &Size);
90
91
#if NTDDI_VERSION >= NTDDI_WIN8
92
    Map = winapi::CreateFileMappingFromApp(
93
        File, nullptr, winapi::PAGE_READONLY_,
94
        static_cast<WasmEdge::winapi::ULONG64_>(Size.QuadPart), nullptr);
95
#else
96
    Map = winapi::CreateFileMappingW(File, nullptr, winapi::PAGE_READONLY_,
97
                                     static_cast<winapi::ULONG_>(Size.HighPart),
98
                                     Size.LowPart, nullptr);
99
#endif
100
    if (Map == nullptr) {
101
      return;
102
    }
103
104
#if NTDDI_VERSION >= NTDDI_WIN8
105
    Address = winapi::MapViewOfFileFromApp(Map, winapi::FILE_MAP_READ_, 0, 0);
106
#else
107
    Address = winapi::MapViewOfFile(Map, winapi::FILE_MAP_READ_, 0, 0, 0);
108
#endif
109
    if (Address == nullptr) {
110
      return;
111
    }
112
  }
113
  ~Implement() noexcept {
114
    if (Address) {
115
      winapi::UnmapViewOfFile(Address);
116
    }
117
    if (Map) {
118
      winapi::CloseHandle(Map);
119
    }
120
    if (File) {
121
      winapi::CloseHandle(File);
122
    }
123
  }
124
  bool ok() const noexcept { return Address != nullptr; }
125
};
126
#else
127
static inline bool kSupported = false;
128
struct Implement {
129
  Implement(const std::filesystem::path &Path) noexcept = default;
130
  bool ok() const noexcept { return false; }
131
}
132
#endif
133
} // namespace
134
135
0
MMap::MMap(const std::filesystem::path &Path) noexcept : Handle(nullptr) {
136
0
  auto NativeHandle = std::make_unique<Implement>(Path);
137
0
  if (!NativeHandle->ok()) {
138
0
    return;
139
0
  }
140
141
0
  Handle = NativeHandle.release();
142
0
}
143
144
0
MMap::~MMap() noexcept {
145
0
  if (!Handle) {
146
0
    return;
147
0
  }
148
149
0
  std::unique_ptr<Implement> NativeHandle(
150
0
      reinterpret_cast<Implement *>(std::exchange(Handle, nullptr)));
151
0
}
152
153
0
void *MMap::address() const noexcept {
154
0
  if (!Handle) {
155
0
    return nullptr;
156
0
  }
157
0
  return reinterpret_cast<const Implement *>(Handle)->Address;
158
0
}
159
160
0
bool MMap::supported() noexcept { return kSupported; }
161
162
} // namespace WasmEdge