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})
if (BUILD_VERSION)
# This leaves a trailing space on the last word, but we actually want that
# because of how it's styled in the title bar.
- set(BUILD_FULLNAME "${REPO_NAME} #${BUILD_VERSION} ")
+ set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ")
else()
set(BUILD_FULLNAME "")
endif()
@@ -64,8 +64,6 @@ add_library(common STATIC
logging/text_formatter.cpp
logging/text_formatter.h
math_util.h
- memory_util.cpp
- memory_util.h
microprofile.cpp
microprofile.h
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) {
return static_cast<T>(value - value % size);
}
+template <typename T>
+constexpr bool Is4KBAligned(T value) {
+ static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
+ return (value & 0xFFF) == 0;
+}
+
+template <typename T>
+constexpr bool IsWordAligned(T value) {
+ static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
+ return (value & 0b11) == 0;
+}
+
} // 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 @@
#ifdef _WIN32
#include <windows.h>
// windows.h needs to be included before other windows headers
-#include <commdlg.h> // for GetSaveFileName
-#include <direct.h> // getcwd
+#include <direct.h> // getcwd
#include <io.h>
#include <shellapi.h>
#include <shlobj.h> // for SHGetFolderPath
#include <tchar.h>
#include "common/string_util.h"
-// 64 bit offsets for windows
+#ifdef _MSC_VER
+// 64 bit offsets for MSVC
#define fseeko _fseeki64
#define ftello _ftelli64
-#define atoll _atoi64
+#define fileno _fileno
+#endif
+
+// 64 bit offsets for MSVC and MinGW. MinGW also needs this for using _wstat64
#define stat _stat64
#define fstat _fstat64
-#define fileno _fileno
+
#else
#ifdef __APPLE__
#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) {
return 0;
}
+std::vector<u8> HexStringToVector(std::string_view str, bool little_endian) {
+ std::vector<u8> out(str.size() / 2);
+ if (little_endian) {
+ for (std::size_t i = str.size() - 2; i <= str.size(); i -= 2)
+ out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
+ } else {
+ for (std::size_t i = 0; i < str.size(); i += 2)
+ out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
+ }
+ return out;
+}
+
+std::string HexVectorToString(const std::vector<u8>& vector, bool upper) {
+ std::string out;
+ for (u8 c : vector)
+ out += fmt::format(upper ? "{:02X}" : "{:02x}", c);
+ return out;
+}
+
std::array<u8, 16> operator""_array16(const char* str, std::size_t len) {
if (len != 32) {
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 @@
#include <array>
#include <cstddef>
#include <string>
+#include <vector>
#include <fmt/format.h>
#include "common/common_types.h"
@@ -14,6 +15,8 @@ namespace Common {
u8 ToHexNibble(char c1);
+std::vector<u8> HexStringToVector(std::string_view str, bool little_endian);
+
template <std::size_t Size, bool le = false>
std::array<u8, Size> HexStringToArray(std::string_view str) {
std::array<u8, Size> out{};
@@ -27,6 +30,8 @@ std::array<u8, Size> HexStringToArray(std::string_view str) {
return out;
}
+std::string HexVectorToString(const std::vector<u8>& vector, bool upper = true);
+
template <std::size_t Size>
std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) {
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) {
SUB(Service, NFP) \
SUB(Service, NIFM) \
SUB(Service, NIM) \
+ SUB(Service, NPNS) \
SUB(Service, NS) \
SUB(Service, NVDRV) \
SUB(Service, PCIE) \
@@ -211,10 +212,12 @@ void DebuggerBackend::Write(const Entry& entry) {
SUB(Service, PM) \
SUB(Service, PREPO) \
SUB(Service, PSC) \
+ SUB(Service, PSM) \
SUB(Service, SET) \
SUB(Service, SM) \
SUB(Service, SPL) \
SUB(Service, SSL) \
+ SUB(Service, TCAP) \
SUB(Service, Time) \
SUB(Service, USB) \
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 {
Service_NFP, ///< The NFP service
Service_NIFM, ///< The NIFM (Network interface) service
Service_NIM, ///< The NIM service
+ Service_NPNS, ///< The NPNS service
Service_NS, ///< The NS services
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
Service_PCIE, ///< The PCIe service
@@ -91,10 +92,12 @@ enum class Class : ClassType {
Service_PM, ///< The PM service
Service_PREPO, ///< The PREPO (Play report) service
Service_PSC, ///< The PSC service
+ Service_PSM, ///< The PSM service
Service_SET, ///< The SET (Settings) service
Service_SM, ///< The SM (Service manager) service
Service_SPL, ///< The SPL service
Service_SSL, ///< The SSL service
+ Service_TCAP, ///< The TCAP service.
Service_Time, ///< The time service
Service_USB, ///< The USB (Universal Serial Bus) service
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 @@
-// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "common/logging/log.h"
-#include "common/memory_util.h"
-
-#ifdef _WIN32
-#include <windows.h>
-// Windows.h needs to be included before psapi.h
-#include <psapi.h>
-#include "common/common_funcs.h"
-#include "common/string_util.h"
-#else
-#include <cstdlib>
-#include <sys/mman.h>
-#endif
-
-#if !defined(_WIN32) && defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
-#include <unistd.h>
-#define PAGE_MASK (getpagesize() - 1)
-#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
-#endif
-
-// This is purposely not a full wrapper for virtualalloc/mmap, but it
-// provides exactly the primitive operations that Dolphin needs.
-
-void* AllocateExecutableMemory(std::size_t size, bool low) {
-#if defined(_WIN32)
- void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-#else
- static char* map_hint = nullptr;
-#if defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
- // This OS has no flag to enforce allocation below the 4 GB boundary,
- // but if we hint that we want a low address it is very likely we will
- // get one.
- // An older version of this code used MAP_FIXED, but that has the side
- // effect of discarding already mapped pages that happen to be in the
- // requested virtual memory range (such as the emulated RAM, sometimes).
- if (low && (!map_hint))
- map_hint = (char*)round_page(512 * 1024 * 1024); /* 0.5 GB rounded up to the next page */
-#endif
- void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_ANON | MAP_PRIVATE
-#if defined(ARCHITECTURE_x86_64) && defined(MAP_32BIT)
- | (low ? MAP_32BIT : 0)
-#endif
- ,
- -1, 0);
-#endif /* defined(_WIN32) */
-
-#ifdef _WIN32
- if (ptr == nullptr) {
-#else
- if (ptr == MAP_FAILED) {
- ptr = nullptr;
-#endif
- LOG_ERROR(Common_Memory, "Failed to allocate executable memory");
- }
-#if !defined(_WIN32) && defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
- else {
- if (low) {
- map_hint += size;
- map_hint = (char*)round_page(map_hint); /* round up to the next page */
- }
- }
-#endif
-
-#if EMU_ARCH_BITS == 64
- if ((u64)ptr >= 0x80000000 && low == true)
- LOG_ERROR(Common_Memory, "Executable memory ended up above 2GB!");
-#endif
-
- return ptr;
-}
-
-void* AllocateMemoryPages(std::size_t size) {
-#ifdef _WIN32
- void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE);
-#else
- void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
-
- if (ptr == MAP_FAILED)
- ptr = nullptr;
-#endif
-
- if (ptr == nullptr)
- LOG_ERROR(Common_Memory, "Failed to allocate raw memory");
-
- return ptr;
-}
-
-void* AllocateAlignedMemory(std::size_t size, std::size_t alignment) {
-#ifdef _WIN32
- void* ptr = _aligned_malloc(size, alignment);
-#else
- void* ptr = nullptr;
-#ifdef ANDROID
- ptr = memalign(alignment, size);
-#else
- if (posix_memalign(&ptr, alignment, size) != 0)
- LOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
-#endif
-#endif
-
- if (ptr == nullptr)
- LOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
-
- return ptr;
-}
-
-void FreeMemoryPages(void* ptr, std::size_t size) {
- if (ptr) {
-#ifdef _WIN32
- if (!VirtualFree(ptr, 0, MEM_RELEASE))
- LOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n{}", GetLastErrorMsg());
-#else
- munmap(ptr, size);
-#endif
- }
-}
-
-void FreeAlignedMemory(void* ptr) {
- if (ptr) {
-#ifdef _WIN32
- _aligned_free(ptr);
-#else
- free(ptr);
-#endif
- }
-}
-
-void WriteProtectMemory(void* ptr, std::size_t size, bool allowExecute) {
-#ifdef _WIN32
- DWORD oldValue;
- if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
- LOG_ERROR(Common_Memory, "WriteProtectMemory failed!\n{}", GetLastErrorMsg());
-#else
- mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ);
-#endif
-}
-
-void UnWriteProtectMemory(void* ptr, std::size_t size, bool allowExecute) {
-#ifdef _WIN32
- DWORD oldValue;
- if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
- &oldValue))
- LOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n{}", GetLastErrorMsg());
-#else
- mprotect(ptr, size,
- allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
-#endif
-}
-
-std::string MemUsage() {
-#ifdef _WIN32
-#pragma comment(lib, "psapi")
- DWORD processID = GetCurrentProcessId();
- HANDLE hProcess;
- PROCESS_MEMORY_COUNTERS pmc;
- std::string Ret;
-
- // Print information about the memory usage of the process.
-
- hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
- if (nullptr == hProcess)
- return "MemUsage Error";
-
- if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
- Ret = fmt::format("{} K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7));
-
- CloseHandle(hProcess);
- return Ret;
-#else
- return "";
-#endif
-}
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 @@
-// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <cstddef>
-#include <string>
-
-void* AllocateExecutableMemory(std::size_t size, bool low = true);
-void* AllocateMemoryPages(std::size_t size);
-void FreeMemoryPages(void* ptr, std::size_t size);
-void* AllocateAlignedMemory(std::size_t size, std::size_t alignment);
-void FreeAlignedMemory(void* ptr);
-void WriteProtectMemory(void* ptr, std::size_t size, bool executable = false);
-void UnWriteProtectMemory(void* ptr, std::size_t size, bool allowExecute = false);
-std::string MemUsage();
-
-inline int GetPageSize() {
- return 4096;
-}
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";
constexpr char PARAM_SEPARATOR_ESCAPE[] = "$1";
constexpr char ESCAPE_CHARACTER_ESCAPE[] = "$2";
+/// A placeholder for empty param packages to avoid empty strings
+/// (they may be recognized as "not set" by some frontend libraries like qt)
+constexpr char EMPTY_PLACEHOLDER[] = "[empty]";
+
ParamPackage::ParamPackage(const std::string& serialized) {
+ if (serialized == EMPTY_PLACEHOLDER) {
+ return;
+ }
+
std::vector<std::string> pairs;
Common::SplitString(serialized, PARAM_SEPARATOR, pairs);
@@ -46,7 +54,7 @@ ParamPackage::ParamPackage(std::initializer_list<DataType::value_type> list) : d
std::string ParamPackage::Serialize() const {
if (data.empty())
- return "";
+ return EMPTY_PLACEHOLDER;
std::string result;
@@ -120,4 +128,12 @@ bool ParamPackage::Has(const std::string& key) const {
return data.find(key) != data.end();
}
+void ParamPackage::Erase(const std::string& key) {
+ data.erase(key);
+}
+
+void ParamPackage::Clear() {
+ data.clear();
+}
+
} // 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:
void Set(const std::string& key, int value);
void Set(const std::string& key, float value);
bool Has(const std::string& key) const;
+ void Erase(const std::string& key);
+ void Clear();
private:
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 {
/// Completion method, called once all fields have been visited
virtual void Complete() = 0;
+ virtual bool SubmitTestcase() = 0;
};
/**
@@ -178,6 +179,9 @@ struct NullVisitor : public VisitorInterface {
void Visit(const Field<std::chrono::microseconds>& /*field*/) override {}
void Complete() override {}
+ bool SubmitTestcase() override {
+ return false;
+ }
};
/// 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 @@
#pragma once
#include <string>
+#include "common/common_types.h"
namespace Common {
struct WebResult {