summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt4
-rw-r--r--src/common/alignment.h12
-rw-r--r--src/common/file_util.cpp13
-rw-r--r--src/common/hex_util.cpp19
-rw-r--r--src/common/hex_util.h5
-rw-r--r--src/common/logging/backend.cpp3
-rw-r--r--src/common/logging/log.h3
-rw-r--r--src/common/memory_util.cpp177
-rw-r--r--src/common/memory_util.h21
-rw-r--r--src/common/param_package.cpp18
-rw-r--r--src/common/param_package.h2
-rw-r--r--src/common/telemetry.h4
-rw-r--r--src/common/web_result.h1
13 files changed, 75 insertions, 207 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8985e4367..eccd8f64a 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -29,7 +29,7 @@ if ($ENV{CI})
29 if (BUILD_VERSION) 29 if (BUILD_VERSION)
30 # This leaves a trailing space on the last word, but we actually want that 30 # This leaves a trailing space on the last word, but we actually want that
31 # because of how it's styled in the title bar. 31 # because of how it's styled in the title bar.
32 set(BUILD_FULLNAME "${REPO_NAME} #${BUILD_VERSION} ") 32 set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ")
33 else() 33 else()
34 set(BUILD_FULLNAME "") 34 set(BUILD_FULLNAME "")
35 endif() 35 endif()
@@ -64,8 +64,6 @@ add_library(common STATIC
64 logging/text_formatter.cpp 64 logging/text_formatter.cpp
65 logging/text_formatter.h 65 logging/text_formatter.h
66 math_util.h 66 math_util.h
67 memory_util.cpp
68 memory_util.h
69 microprofile.cpp 67 microprofile.cpp
70 microprofile.h 68 microprofile.h
71 microprofileui.h 69 microprofileui.h
diff --git a/src/common/alignment.h b/src/common/alignment.h
index 225770fab..d94a2291f 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -19,4 +19,16 @@ constexpr T AlignDown(T value, std::size_t size) {
19 return static_cast<T>(value - value % size); 19 return static_cast<T>(value - value % size);
20} 20}
21 21
22template <typename T>
23constexpr bool Is4KBAligned(T value) {
24 static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
25 return (value & 0xFFF) == 0;
26}
27
28template <typename T>
29constexpr bool IsWordAligned(T value) {
30 static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
31 return (value & 0b11) == 0;
32}
33
22} // namespace Common 34} // namespace Common
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 548463787..b52492da6 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -15,21 +15,24 @@
15#ifdef _WIN32 15#ifdef _WIN32
16#include <windows.h> 16#include <windows.h>
17// windows.h needs to be included before other windows headers 17// windows.h needs to be included before other windows headers
18#include <commdlg.h> // for GetSaveFileName 18#include <direct.h> // getcwd
19#include <direct.h> // getcwd
20#include <io.h> 19#include <io.h>
21#include <shellapi.h> 20#include <shellapi.h>
22#include <shlobj.h> // for SHGetFolderPath 21#include <shlobj.h> // for SHGetFolderPath
23#include <tchar.h> 22#include <tchar.h>
24#include "common/string_util.h" 23#include "common/string_util.h"
25 24
26// 64 bit offsets for windows 25#ifdef _MSC_VER
26// 64 bit offsets for MSVC
27#define fseeko _fseeki64 27#define fseeko _fseeki64
28#define ftello _ftelli64 28#define ftello _ftelli64
29#define atoll _atoi64 29#define fileno _fileno
30#endif
31
32// 64 bit offsets for MSVC and MinGW. MinGW also needs this for using _wstat64
30#define stat _stat64 33#define stat _stat64
31#define fstat _fstat64 34#define fstat _fstat64
32#define fileno _fileno 35
33#else 36#else
34#ifdef __APPLE__ 37#ifdef __APPLE__
35#include <sys/param.h> 38#include <sys/param.h>
diff --git a/src/common/hex_util.cpp b/src/common/hex_util.cpp
index 589ae5cbf..5b63f9e81 100644
--- a/src/common/hex_util.cpp
+++ b/src/common/hex_util.cpp
@@ -18,6 +18,25 @@ u8 ToHexNibble(char c1) {
18 return 0; 18 return 0;
19} 19}
20 20
21std::vector<u8> HexStringToVector(std::string_view str, bool little_endian) {
22 std::vector<u8> out(str.size() / 2);
23 if (little_endian) {
24 for (std::size_t i = str.size() - 2; i <= str.size(); i -= 2)
25 out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
26 } else {
27 for (std::size_t i = 0; i < str.size(); i += 2)
28 out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
29 }
30 return out;
31}
32
33std::string HexVectorToString(const std::vector<u8>& vector, bool upper) {
34 std::string out;
35 for (u8 c : vector)
36 out += fmt::format(upper ? "{:02X}" : "{:02x}", c);
37 return out;
38}
39
21std::array<u8, 16> operator""_array16(const char* str, std::size_t len) { 40std::array<u8, 16> operator""_array16(const char* str, std::size_t len) {
22 if (len != 32) { 41 if (len != 32) {
23 LOG_ERROR(Common, 42 LOG_ERROR(Common,
diff --git a/src/common/hex_util.h b/src/common/hex_util.h
index 863a5ccd9..68f003cb6 100644
--- a/src/common/hex_util.h
+++ b/src/common/hex_util.h
@@ -7,6 +7,7 @@
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <string> 9#include <string>
10#include <vector>
10#include <fmt/format.h> 11#include <fmt/format.h>
11#include "common/common_types.h" 12#include "common/common_types.h"
12 13
@@ -14,6 +15,8 @@ namespace Common {
14 15
15u8 ToHexNibble(char c1); 16u8 ToHexNibble(char c1);
16 17
18std::vector<u8> HexStringToVector(std::string_view str, bool little_endian);
19
17template <std::size_t Size, bool le = false> 20template <std::size_t Size, bool le = false>
18std::array<u8, Size> HexStringToArray(std::string_view str) { 21std::array<u8, Size> HexStringToArray(std::string_view str) {
19 std::array<u8, Size> out{}; 22 std::array<u8, Size> out{};
@@ -27,6 +30,8 @@ std::array<u8, Size> HexStringToArray(std::string_view str) {
27 return out; 30 return out;
28} 31}
29 32
33std::string HexVectorToString(const std::vector<u8>& vector, bool upper = true);
34
30template <std::size_t Size> 35template <std::size_t Size>
31std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) { 36std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) {
32 std::string out; 37 std::string out;
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 31ad72f38..5753b871a 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -203,6 +203,7 @@ void DebuggerBackend::Write(const Entry& entry) {
203 SUB(Service, NFP) \ 203 SUB(Service, NFP) \
204 SUB(Service, NIFM) \ 204 SUB(Service, NIFM) \
205 SUB(Service, NIM) \ 205 SUB(Service, NIM) \
206 SUB(Service, NPNS) \
206 SUB(Service, NS) \ 207 SUB(Service, NS) \
207 SUB(Service, NVDRV) \ 208 SUB(Service, NVDRV) \
208 SUB(Service, PCIE) \ 209 SUB(Service, PCIE) \
@@ -211,10 +212,12 @@ void DebuggerBackend::Write(const Entry& entry) {
211 SUB(Service, PM) \ 212 SUB(Service, PM) \
212 SUB(Service, PREPO) \ 213 SUB(Service, PREPO) \
213 SUB(Service, PSC) \ 214 SUB(Service, PSC) \
215 SUB(Service, PSM) \
214 SUB(Service, SET) \ 216 SUB(Service, SET) \
215 SUB(Service, SM) \ 217 SUB(Service, SM) \
216 SUB(Service, SPL) \ 218 SUB(Service, SPL) \
217 SUB(Service, SSL) \ 219 SUB(Service, SSL) \
220 SUB(Service, TCAP) \
218 SUB(Service, Time) \ 221 SUB(Service, Time) \
219 SUB(Service, USB) \ 222 SUB(Service, USB) \
220 SUB(Service, VI) \ 223 SUB(Service, VI) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index abbd056ee..d4ec31ec3 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -83,6 +83,7 @@ enum class Class : ClassType {
83 Service_NFP, ///< The NFP service 83 Service_NFP, ///< The NFP service
84 Service_NIFM, ///< The NIFM (Network interface) service 84 Service_NIFM, ///< The NIFM (Network interface) service
85 Service_NIM, ///< The NIM service 85 Service_NIM, ///< The NIM service
86 Service_NPNS, ///< The NPNS service
86 Service_NS, ///< The NS services 87 Service_NS, ///< The NS services
87 Service_NVDRV, ///< The NVDRV (Nvidia driver) service 88 Service_NVDRV, ///< The NVDRV (Nvidia driver) service
88 Service_PCIE, ///< The PCIe service 89 Service_PCIE, ///< The PCIe service
@@ -91,10 +92,12 @@ enum class Class : ClassType {
91 Service_PM, ///< The PM service 92 Service_PM, ///< The PM service
92 Service_PREPO, ///< The PREPO (Play report) service 93 Service_PREPO, ///< The PREPO (Play report) service
93 Service_PSC, ///< The PSC service 94 Service_PSC, ///< The PSC service
95 Service_PSM, ///< The PSM service
94 Service_SET, ///< The SET (Settings) service 96 Service_SET, ///< The SET (Settings) service
95 Service_SM, ///< The SM (Service manager) service 97 Service_SM, ///< The SM (Service manager) service
96 Service_SPL, ///< The SPL service 98 Service_SPL, ///< The SPL service
97 Service_SSL, ///< The SSL service 99 Service_SSL, ///< The SSL service
100 Service_TCAP, ///< The TCAP service.
98 Service_Time, ///< The time service 101 Service_Time, ///< The time service
99 Service_USB, ///< The USB (Universal Serial Bus) service 102 Service_USB, ///< The USB (Universal Serial Bus) service
100 Service_VI, ///< The VI (Video interface) service 103 Service_VI, ///< The VI (Video interface) service
diff --git a/src/common/memory_util.cpp b/src/common/memory_util.cpp
deleted file mode 100644
index 9736fb12a..000000000
--- a/src/common/memory_util.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
1// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6#include "common/memory_util.h"
7
8#ifdef _WIN32
9#include <windows.h>
10// Windows.h needs to be included before psapi.h
11#include <psapi.h>
12#include "common/common_funcs.h"
13#include "common/string_util.h"
14#else
15#include <cstdlib>
16#include <sys/mman.h>
17#endif
18
19#if !defined(_WIN32) && defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
20#include <unistd.h>
21#define PAGE_MASK (getpagesize() - 1)
22#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
23#endif
24
25// This is purposely not a full wrapper for virtualalloc/mmap, but it
26// provides exactly the primitive operations that Dolphin needs.
27
28void* AllocateExecutableMemory(std::size_t size, bool low) {
29#if defined(_WIN32)
30 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
31#else
32 static char* map_hint = nullptr;
33#if defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
34 // This OS has no flag to enforce allocation below the 4 GB boundary,
35 // but if we hint that we want a low address it is very likely we will
36 // get one.
37 // An older version of this code used MAP_FIXED, but that has the side
38 // effect of discarding already mapped pages that happen to be in the
39 // requested virtual memory range (such as the emulated RAM, sometimes).
40 if (low && (!map_hint))
41 map_hint = (char*)round_page(512 * 1024 * 1024); /* 0.5 GB rounded up to the next page */
42#endif
43 void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
44 MAP_ANON | MAP_PRIVATE
45#if defined(ARCHITECTURE_x86_64) && defined(MAP_32BIT)
46 | (low ? MAP_32BIT : 0)
47#endif
48 ,
49 -1, 0);
50#endif /* defined(_WIN32) */
51
52#ifdef _WIN32
53 if (ptr == nullptr) {
54#else
55 if (ptr == MAP_FAILED) {
56 ptr = nullptr;
57#endif
58 LOG_ERROR(Common_Memory, "Failed to allocate executable memory");
59 }
60#if !defined(_WIN32) && defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
61 else {
62 if (low) {
63 map_hint += size;
64 map_hint = (char*)round_page(map_hint); /* round up to the next page */
65 }
66 }
67#endif
68
69#if EMU_ARCH_BITS == 64
70 if ((u64)ptr >= 0x80000000 && low == true)
71 LOG_ERROR(Common_Memory, "Executable memory ended up above 2GB!");
72#endif
73
74 return ptr;
75}
76
77void* AllocateMemoryPages(std::size_t size) {
78#ifdef _WIN32
79 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE);
80#else
81 void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
82
83 if (ptr == MAP_FAILED)
84 ptr = nullptr;
85#endif
86
87 if (ptr == nullptr)
88 LOG_ERROR(Common_Memory, "Failed to allocate raw memory");
89
90 return ptr;
91}
92
93void* AllocateAlignedMemory(std::size_t size, std::size_t alignment) {
94#ifdef _WIN32
95 void* ptr = _aligned_malloc(size, alignment);
96#else
97 void* ptr = nullptr;
98#ifdef ANDROID
99 ptr = memalign(alignment, size);
100#else
101 if (posix_memalign(&ptr, alignment, size) != 0)
102 LOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
103#endif
104#endif
105
106 if (ptr == nullptr)
107 LOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
108
109 return ptr;
110}
111
112void FreeMemoryPages(void* ptr, std::size_t size) {
113 if (ptr) {
114#ifdef _WIN32
115 if (!VirtualFree(ptr, 0, MEM_RELEASE))
116 LOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n{}", GetLastErrorMsg());
117#else
118 munmap(ptr, size);
119#endif
120 }
121}
122
123void FreeAlignedMemory(void* ptr) {
124 if (ptr) {
125#ifdef _WIN32
126 _aligned_free(ptr);
127#else
128 free(ptr);
129#endif
130 }
131}
132
133void WriteProtectMemory(void* ptr, std::size_t size, bool allowExecute) {
134#ifdef _WIN32
135 DWORD oldValue;
136 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
137 LOG_ERROR(Common_Memory, "WriteProtectMemory failed!\n{}", GetLastErrorMsg());
138#else
139 mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ);
140#endif
141}
142
143void UnWriteProtectMemory(void* ptr, std::size_t size, bool allowExecute) {
144#ifdef _WIN32
145 DWORD oldValue;
146 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
147 &oldValue))
148 LOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n{}", GetLastErrorMsg());
149#else
150 mprotect(ptr, size,
151 allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
152#endif
153}
154
155std::string MemUsage() {
156#ifdef _WIN32
157#pragma comment(lib, "psapi")
158 DWORD processID = GetCurrentProcessId();
159 HANDLE hProcess;
160 PROCESS_MEMORY_COUNTERS pmc;
161 std::string Ret;
162
163 // Print information about the memory usage of the process.
164
165 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
166 if (nullptr == hProcess)
167 return "MemUsage Error";
168
169 if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
170 Ret = fmt::format("{} K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7));
171
172 CloseHandle(hProcess);
173 return Ret;
174#else
175 return "";
176#endif
177}
diff --git a/src/common/memory_util.h b/src/common/memory_util.h
deleted file mode 100644
index aad071979..000000000
--- a/src/common/memory_util.h
+++ /dev/null
@@ -1,21 +0,0 @@
1// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <cstddef>
8#include <string>
9
10void* AllocateExecutableMemory(std::size_t size, bool low = true);
11void* AllocateMemoryPages(std::size_t size);
12void FreeMemoryPages(void* ptr, std::size_t size);
13void* AllocateAlignedMemory(std::size_t size, std::size_t alignment);
14void FreeAlignedMemory(void* ptr);
15void WriteProtectMemory(void* ptr, std::size_t size, bool executable = false);
16void UnWriteProtectMemory(void* ptr, std::size_t size, bool allowExecute = false);
17std::string MemUsage();
18
19inline int GetPageSize() {
20 return 4096;
21}
diff --git a/src/common/param_package.cpp b/src/common/param_package.cpp
index 9526ca0c6..b916b4866 100644
--- a/src/common/param_package.cpp
+++ b/src/common/param_package.cpp
@@ -20,7 +20,15 @@ constexpr char KEY_VALUE_SEPARATOR_ESCAPE[] = "$0";
20constexpr char PARAM_SEPARATOR_ESCAPE[] = "$1"; 20constexpr char PARAM_SEPARATOR_ESCAPE[] = "$1";
21constexpr char ESCAPE_CHARACTER_ESCAPE[] = "$2"; 21constexpr char ESCAPE_CHARACTER_ESCAPE[] = "$2";
22 22
23/// A placeholder for empty param packages to avoid empty strings
24/// (they may be recognized as "not set" by some frontend libraries like qt)
25constexpr char EMPTY_PLACEHOLDER[] = "[empty]";
26
23ParamPackage::ParamPackage(const std::string& serialized) { 27ParamPackage::ParamPackage(const std::string& serialized) {
28 if (serialized == EMPTY_PLACEHOLDER) {
29 return;
30 }
31
24 std::vector<std::string> pairs; 32 std::vector<std::string> pairs;
25 Common::SplitString(serialized, PARAM_SEPARATOR, pairs); 33 Common::SplitString(serialized, PARAM_SEPARATOR, pairs);
26 34
@@ -46,7 +54,7 @@ ParamPackage::ParamPackage(std::initializer_list<DataType::value_type> list) : d
46 54
47std::string ParamPackage::Serialize() const { 55std::string ParamPackage::Serialize() const {
48 if (data.empty()) 56 if (data.empty())
49 return ""; 57 return EMPTY_PLACEHOLDER;
50 58
51 std::string result; 59 std::string result;
52 60
@@ -120,4 +128,12 @@ bool ParamPackage::Has(const std::string& key) const {
120 return data.find(key) != data.end(); 128 return data.find(key) != data.end();
121} 129}
122 130
131void ParamPackage::Erase(const std::string& key) {
132 data.erase(key);
133}
134
135void ParamPackage::Clear() {
136 data.clear();
137}
138
123} // namespace Common 139} // namespace Common
diff --git a/src/common/param_package.h b/src/common/param_package.h
index 7842cd4ef..6a0a9b656 100644
--- a/src/common/param_package.h
+++ b/src/common/param_package.h
@@ -32,6 +32,8 @@ public:
32 void Set(const std::string& key, int value); 32 void Set(const std::string& key, int value);
33 void Set(const std::string& key, float value); 33 void Set(const std::string& key, float value);
34 bool Has(const std::string& key) const; 34 bool Has(const std::string& key) const;
35 void Erase(const std::string& key);
36 void Clear();
35 37
36private: 38private:
37 DataType data; 39 DataType data;
diff --git a/src/common/telemetry.h b/src/common/telemetry.h
index 8d6ab986b..854a73fae 100644
--- a/src/common/telemetry.h
+++ b/src/common/telemetry.h
@@ -153,6 +153,7 @@ struct VisitorInterface : NonCopyable {
153 153
154 /// Completion method, called once all fields have been visited 154 /// Completion method, called once all fields have been visited
155 virtual void Complete() = 0; 155 virtual void Complete() = 0;
156 virtual bool SubmitTestcase() = 0;
156}; 157};
157 158
158/** 159/**
@@ -178,6 +179,9 @@ struct NullVisitor : public VisitorInterface {
178 void Visit(const Field<std::chrono::microseconds>& /*field*/) override {} 179 void Visit(const Field<std::chrono::microseconds>& /*field*/) override {}
179 180
180 void Complete() override {} 181 void Complete() override {}
182 bool SubmitTestcase() override {
183 return false;
184 }
181}; 185};
182 186
183/// Appends build-specific information to the given FieldCollection, 187/// Appends build-specific information to the given FieldCollection,
diff --git a/src/common/web_result.h b/src/common/web_result.h
index 969926674..8bfa2141d 100644
--- a/src/common/web_result.h
+++ b/src/common/web_result.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8#include "common/common_types.h"
8 9
9namespace Common { 10namespace Common {
10struct WebResult { 11struct WebResult {