Compare commits

...

75 Commits

Author SHA1 Message Date
Subv
d84eb9dac6 CPU: Save and restore the TPIDR_EL0 system register on every context switch.
Note that there's currently a dynarmic bug preventing this register from being written.
2018-07-20 19:57:45 -05:00
bunnei
f36affdbe3 Merge pull request #730 from lioncash/string
gl_shader_decompiler: Remove unnecessary const from return values
2018-07-19 20:46:43 -07:00
bunnei
ce66a188d0 Merge pull request #729 from lioncash/simplify
pl_u: Simplify WriteBuffer() calls in GetSharedFontInOrderOfPriority()
2018-07-19 20:46:11 -07:00
Lioncash
c2121cb059 gl_shader_decompiler: Remove unnecessary const from return values
This adds nothing from a behavioral point of view, and can inhibit the
move constructor/RVO
2018-07-19 20:11:04 -04:00
Lioncash
1bdb67440b pl_u: Simplify WriteBuffer() calls in GetSharedFontInOrderOfPriority()
With the new overload, we can simply pass the container directly.
2018-07-19 19:50:30 -04:00
bunnei
d3cfaf95c8 Merge pull request #726 from lioncash/overload
hle_ipc: Introduce generic WriteBuffer overload for multiple container types
2018-07-19 16:18:38 -07:00
bunnei
0b13ce1435 Merge pull request #725 from lioncash/bytes
pl_u: Specify correct size for buffers in GetSharedFontInOrderOfPriority()
2018-07-19 16:16:30 -07:00
bunnei
af08034c71 Merge pull request #728 from Subv/acc_profile
HLE/ACC: Change the default user id and small improvements to the way we handle profiles
2018-07-19 16:15:01 -07:00
bunnei
2aeb3355e4 Merge pull request #727 from Subv/acc_users
HLE/ACC: Write a single whole user id in ListAllUsers and ListOpenUsers.
2018-07-19 16:13:45 -07:00
bunnei
c6352ffc58 Merge pull request #724 from lioncash/printf
pl_u: Remove printf specifier in log call in a log call in GetSharedFontInOrderOfPriority()
2018-07-19 16:13:07 -07:00
bunnei
ec468c990d Merge pull request #723 from lioncash/gdb
gdbstub: Get rid of a few signed/unsigned comparisons
2018-07-19 16:12:40 -07:00
bunnei
f43d8ea523 Merge pull request #722 from lioncash/signed
hid: Resolve a signed/unsigned comparison warning
2018-07-19 16:12:15 -07:00
bunnei
2194308245 Merge pull request #721 from lioncash/svc
svc: Correct always true assertion case in SetThreadCoreMask
2018-07-19 16:11:40 -07:00
bunnei
b5c77313de Merge pull request #719 from lioncash/docs
loader: Amend Doxygen comments
2018-07-19 16:11:09 -07:00
bunnei
dd0446ff43 Merge pull request #718 from lioncash/read
loader/nso: Check if read succeeded in IdentifyFile() before checking magic value
2018-07-19 16:10:29 -07:00
bunnei
31413f0d2f Merge pull request #717 from lioncash/explicit
hle/service: Make constructors explicit where applicable
2018-07-19 16:08:07 -07:00
Subv
05549e45c5 HLE/ACC: Return an IProfile that is consistent with what was requested.
The default username for now is "yuzu".
We should eventually allow the creation of users in the emulator and have the ability to modify their parameters.
2018-07-19 16:53:42 -05:00
Subv
50e2777724 HLE/ACC: Change the default user id to be consistent with what we tell games on startup.
In IApplicationFunctions::PopLaunchParameter we tell the games that they were launched as user id 1.
2018-07-19 16:51:55 -05:00
Subv
b102815f1f HLE/ACC: Write a single whole user id in ListAllUsers and ListOpenUsers.
We only emulate a single user id for now.
2018-07-19 16:19:46 -05:00
bunnei
7244671137 Merge pull request #716 from lioncash/construct
nvflinger: Emplace Display instances directly
2018-07-19 14:18:29 -07:00
Lioncash
ff500a7b68 hle_ipc: Introduce generic WriteBuffer overload for multiple container types
This introduces a slightly more generic variant of WriteBuffer().
Notably, this variant doesn't constrain the arguments to only accepting
std::vector instances. It accepts whatever adheres to the
ContiguousContainer concept in the C++ standard library.

This essentially means, std::array, std::string, and std::vector can be
used directly with this interface. The interface no longer forces you to
solely use containers that dynamically allocate.

To ensure our overloads play nice with one another, we only enable the
container-based WriteBuffer if the argument is not a pointer, otherwise
we fall back to the pointer-based one.
2018-07-19 17:05:12 -04:00
bunnei
eb9b55eafe Merge pull request #715 from lioncash/const-ref
nvdrv: Take std::string by const reference in GetDevice()
2018-07-19 13:27:48 -07:00
Sebastian Valle
78dd1cd441 Merge pull request #720 from Subv/getentrytype_root
Filesystem: Return EntryType::Directory for the root directory.
2018-07-19 15:23:32 -05:00
Lioncash
df001e83b1 pl_u: Specify correct size for buffers in GetSharedFontInOrderOfPriority()
This WriteBuffer overload expects its size argument to be in bytes, not
elements.
2018-07-19 15:57:58 -04:00
Lioncash
b879fb84a2 svc: Correct always true assertion case in SetThreadCoreMask
The reason this would never be true is that ideal_processor is a u8 and
THREADPROCESSORID_DEFAULT is an s32. In this case, it boils down to how
arithmetic conversions are performed before performing the comparison.

If an unsigned value has a lesser conversion rank (aka smaller size)
than the signed type being compared, then the unsigned value is promoted
to the signed value (i.e. u8 -> s32 happens before the comparison). No
sign-extension occurs here either.

An alternative phrasing:

Say we have a variable named core and it's given a value of -2.

u8 core = -2;

This becomes 254 due to the lack of sign. During integral promotion to
the signed type, this still remains as 254, and therefore the condition
will always be true, because no matter what value the u8 is given it
will never be -2 in terms of 32 bits.

Now, if one type was a s32 and one was a u32, this would be entirely
different, since they have the same bit width (and the signed type would
be converted to unsigned instead of the other way around) but would
still have its representation preserved in terms of bits, allowing the
comparison to be false in some cases, as opposed to being true all the
time.

---

We also get rid of two signed/unsigned comparison warnings while we're
at it.
2018-07-19 15:46:17 -04:00
Lioncash
68c1ffdd1c pl_u: Remove printf specifier in log call in a log call in GetSharedFontInOrderOfPriority()
This can just use the fmt specifiers and be type-agnostic.
2018-07-19 15:44:04 -04:00
Sebastian Valle
7eace8f512 Merge pull request #714 from lioncash/index
hle_ipc: Amend usage of buffer_index within one of HLERequestContext's WriteBuffer() overloads
2018-07-19 14:36:34 -05:00
bunnei
38b35e752b Merge pull request #712 from lioncash/fsp
fsp_srv: Misc individual changes
2018-07-19 12:31:33 -07:00
Lioncash
c945226973 gdbstub: Get rid of a few signed/unsigned comparisons
Ensures both operands in comparisons are the same signedness.
2018-07-19 15:27:01 -04:00
Lioncash
a37a47448d hid: Use a ranged-for loops in UpdatePadCallback
Modernizes the loops themselves while also getting rid of a signed/unsigned
comparison in a loop condition.
2018-07-19 15:11:08 -04:00
Lioncash
95103a1b7b hid: Use HID_NUM_LAYOUTS constant for indicating size of the layouts array
Gets rid of the use of a magic constant
2018-07-19 15:07:36 -04:00
bunnei
427fc4ac6b Merge pull request #713 from lioncash/filesys
filesystem: Minor changes
2018-07-19 11:49:06 -07:00
bunnei
e91ba6c057 Merge pull request #711 from lioncash/swap
common/swap: Minor changes
2018-07-19 11:48:16 -07:00
bunnei
d6c7a05239 Merge pull request #710 from lioncash/unused
common/common_funcs: Remove unused rotation functions
2018-07-19 11:43:41 -07:00
bunnei
1034bcc742 Merge pull request #694 from lioncash/warn
loader/{nro, nso}: Resolve compilation warnings
2018-07-19 11:43:14 -07:00
Subv
e5c916a27c Filesystem: Return EntryType::Directory for the root directory.
It is unknown if this is correct behavior, but it makes sense and fixes a regression with Stardew Valley.
2018-07-19 13:11:09 -05:00
Lioncash
50d08beed2 loader: Amend Doxygen comments
These weren't adjusted when VFS was introduced
2018-07-19 14:04:33 -04:00
bunnei
bbc31ba6af Merge pull request #709 from lioncash/thread-local
common/misc: Deduplicate code in GetLastErrorMsg()
2018-07-19 10:00:48 -07:00
bunnei
130a02f330 Merge pull request #708 from lioncash/xbyak
externals: Update Xbyak to 5.65
2018-07-19 10:00:06 -07:00
bunnei
8176ab3a07 Merge pull request #707 from lioncash/catch
externals: Update catch to v2.2.3
2018-07-19 09:59:44 -07:00
Lioncash
9b22f856c2 loader/nso: Check if read succeeded in IdentifyFile() before checking magic value
We should always assume the filesystem is volatile and check each IO
operation. While we're at it reorganize checks so that early-out errors
are near one another.
2018-07-19 12:43:21 -04:00
Lioncash
c061c2bf3c hle/service: Make constructors explicit where applicable
Prevents implicit construction and makes these lingering non-explicit
constructors consistent with the rest of the other classes in services.
2018-07-19 12:25:02 -04:00
Lioncash
f3daecafeb nvflinger: Emplace Display instances directly
We can use emplace_back to construct the Display instances directly,
instead of constructing them separately and copying them, avoiding the
need to copy std::string and std::vector instances that are part of the
Display struct.
2018-07-19 11:50:12 -04:00
bunnei
04f7a7036a Merge pull request #705 from lioncash/string-ref
file_util: return string by const reference for GetExeDirectory()
2018-07-19 08:47:06 -07:00
bunnei
cbf43225a9 Merge pull request #704 from lioncash/string
string_util: Remove AsciiToHex()
2018-07-19 08:46:40 -07:00
bunnei
f1d7486eac Merge pull request #703 from lioncash/const
savedata_factory: Make SaveDataDescriptor's DebugInfo() function a const member function
2018-07-19 08:46:15 -07:00
bunnei
b0334af05b Merge pull request #702 from lioncash/initialize
partition_filesystem: Ensure all class members of PartitionFilesystem are initialized
2018-07-19 08:45:54 -07:00
bunnei
1bf7ae79c8 Merge pull request #701 from lioncash/moving
content_archive: Minor changes
2018-07-19 08:41:42 -07:00
Lioncash
af2698dcea hle_ipc: Amend usage of buffer_index within one of HLERequestContext's WriteBuffer() overloads
Previously, the buffer_index parameter was unused, causing all writes to
use the buffer index of zero, which is not necessarily what is wanted
all the time.

Thankfully, all current usages don't use a buffer index other than zero,
so this just prevents a bug before it has a chance to spring.
2018-07-19 11:10:16 -04:00
Lioncash
6c1ba02e0c fsp_srv: Remove unnecessary vector construction in IFile's Write() function
We can avoid constructing a std::vector here by simply passing a pointer
to the original data and the size of the copy we wish to perform to the
backend's Write() function instead, avoiding copying the data where it's
otherwise not needed.
2018-07-19 11:01:07 -04:00
Lioncash
3e9b79e088 fsp_srv: Remove unnecessary std::vector construction in IDirectory's Read() function
We were using a second std::vector as a buffer to convert another
std::vector's data into a byte sequence, however we can just use
pointers to the original data and use them directly with WriteBuffer,
which avoids copying the data at all into a separate std::vector.

We simply cast the pointers to u8* (which is allowed by the standard,
given std::uint8_t is an alias for unsigned char on platforms that we
support).
2018-07-19 10:46:54 -04:00
Lioncash
5da4c78c6a filesystem: std::move VirtualDir instance in VfsDirectoryServiceWrapper's constructor
Avoids unnecessary atomic reference count incrementing and decrementing
2018-07-19 10:34:11 -04:00
Lioncash
abbf038191 filesystem: Use std::string's empty() function instead of comparing against a literal
This is simply a basic value check as opposed to potentially doing
string based operations (unlikely, but still, avoiding it is free).
2018-07-19 10:32:23 -04:00
Lioncash
2cc0ef83cf filesystem: Remove pragma disabling global optimizations
This was just an artifact missed during PR review.
2018-07-19 10:30:53 -04:00
Lioncash
f317080f40 fsp_srv: Make IStorage constructor explicit
Prevents implicit conversions.
2018-07-19 10:04:16 -04:00
Lioncash
910ad2e110 fsp_srv: Add missing includes
Gets rid of relying on indirect inclusions.
2018-07-19 10:03:17 -04:00
Lioncash
6be342118a fsp_srv: Resolve sign-mismatch warnings in assertion comparisons 2018-07-19 09:58:32 -04:00
Lioncash
d6e9b96e2f fsp_srv: Respect write length in Write()
Previously we were just copying the data whole-sale, even if the length
was less than the total data size. This effectively makes the
actual_data vector useless, which is likely not intended.

Instead, amend this to only copy the given length amount of data.

At the same time, we can avoid zeroing out the data before using it by
passing iterators to the constructor instead of a size.
2018-07-19 09:57:48 -04:00
Lioncash
5c47ea1a4e common/swap: Remove unnecessary const on return value of swap() 2018-07-19 09:35:54 -04:00
Lioncash
0a868641fa common/swap: Use static_cast where applicable 2018-07-19 09:35:13 -04:00
Lioncash
1edf4dd7ef common/swap: Use using aliases where applicable 2018-07-19 09:32:13 -04:00
Lioncash
9128271292 common/common_funcs: Remove unused rotation functions
These are unused and essentially don't provide much benefit either. If
we ever need rotation functions, these can be introduced in a way that
they don't sit in a common_* header and require a bunch of ifdefing to
simply be available
2018-07-19 09:21:23 -04:00
Lioncash
e0b8a35937 common/misc: Deduplicate code in GetLastErrorMsg()
Android and macOS have supported thread_local for quite a while, but
most importantly is that we don't even really need it. Instead of using
a thread-local buffer, we can just return a non-static buffer as a
std::string, avoiding the need for that quality entirely.
2018-07-19 09:15:38 -04:00
Lioncash
ef03d0178a externals: Update Xbyak to 5.65
Keeps the JIT assembler library up to date and ensures we don't run into
any issues that may have been resolved.
2018-07-19 08:38:07 -04:00
Lioncash
25f997097d externals: Update catch to v2.2.3
Keeps the unit-testing library up to date.
2018-07-19 08:33:06 -04:00
Lioncash
63e64f0131 file_util: return string by const reference for GetExeDirectory()
This disallows modifying the internal string buffer (which shouldn't be
modified anyhow).
2018-07-19 01:27:29 -04:00
Lioncash
33fbcb45a7 string_util: Remove AsciiToHex()
Easy TODO
2018-07-18 23:57:15 -04:00
Lioncash
88ba94e8a2 savedata_factory: Make SaveDataDescriptor's DebugInfo() function a const member function
This function doesn't alter class state.
2018-07-18 23:50:07 -04:00
Lioncash
9abc5763b6 partition_filesystem: Ensure all class members of PartitionFilesystem are initialized
Previously is_hfs and pfs_header members wouldn't be initialized in the
constructor, as they were stored in locals instead. This would result in
things like GetName() and PrintDebugInfo() behaving incorrectly.

While we're at it, initialize the members to deterministic values as
well, in case loading ever fails.
2018-07-18 23:45:22 -04:00
Lioncash
4790bb907d content_archive: Make IsDirectoryExeFS() take a shared_ptr as a const reference
There's no need to take this by value when it's possible to avoid
unnecessary copies entirely like this.
2018-07-18 23:19:28 -04:00
Lioncash
87a9bb392b content_archive: Add missing standard includes 2018-07-18 23:18:59 -04:00
Lioncash
0b566f43a1 content_archive: std::move VirtualFile in NCA's constructor
Gets rid of unnecessary atomic reference count incrementing and
decrementing.
2018-07-18 23:13:25 -04:00
Lioncash
55ab369043 loader/nro: Resolve sign mismatch warnings 2018-07-18 22:27:22 -04:00
Lioncash
1831b5ef62 loader/nso: Remove unnecessary vector resizes
We can just initialize these vectors directly via their constructor.
2018-07-18 22:26:41 -04:00
Lioncash
e3a30ccc7c loader/nso: Resolve sign mismatch warnings 2018-07-18 22:26:37 -04:00
63 changed files with 270 additions and 262 deletions

View File

@@ -4,6 +4,8 @@
#pragma once
#include <string>
#if !defined(ARCHITECTURE_x86_64) && !defined(ARCHITECTURE_ARM)
#include <cstdlib> // for exit
#endif
@@ -36,40 +38,6 @@
#define Crash() exit(1)
#endif
// GCC 4.8 defines all the rotate functions now
// Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
#ifdef _rotl
#define rotl _rotl
#else
inline u32 rotl(u32 x, int shift) {
shift &= 31;
if (!shift)
return x;
return (x << shift) | (x >> (32 - shift));
}
#endif
#ifdef _rotr
#define rotr _rotr
#else
inline u32 rotr(u32 x, int shift) {
shift &= 31;
if (!shift)
return x;
return (x >> shift) | (x << (32 - shift));
}
#endif
inline u64 _rotl64(u64 x, unsigned int shift) {
unsigned int n = shift % 64;
return (x << n) | (x >> (64 - n));
}
inline u64 _rotr64(u64 x, unsigned int shift) {
unsigned int n = shift % 64;
return (x >> n) | (x << (64 - n));
}
#else // _MSC_VER
// Locale Cross-Compatibility
@@ -80,17 +48,13 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
}
#define Crash() DebugBreak()
// cstdlib provides these on MSVC
#define rotr _rotr
#define rotl _rotl
#endif // _MSC_VER ndef
// Generic function to get last error message.
// Call directly after the command or use the error num.
// This function might change the error code.
// Defined in Misc.cpp.
const char* GetLastErrorMsg();
std::string GetLastErrorMsg();
namespace Common {

View File

@@ -592,7 +592,7 @@ std::string GetBundleDirectory() {
#endif
#ifdef _WIN32
std::string& GetExeDirectory() {
const std::string& GetExeDirectory() {
static std::string exe_path;
if (exe_path.empty()) {
wchar_t wchar_exe_path[2048];

View File

@@ -133,7 +133,7 @@ std::string GetBundleDirectory();
#endif
#ifdef _WIN32
std::string& GetExeDirectory();
const std::string& GetExeDirectory();
std::string AppDataRoamingDirectory();
#endif

View File

@@ -4,34 +4,28 @@
#include <cstddef>
#ifdef _WIN32
#include <windows.h>
#include <Windows.h>
#else
#include <cerrno>
#include <cstring>
#endif
// Neither Android nor OS X support TLS
#if defined(__APPLE__) || (ANDROID && __clang__)
#define __thread
#endif
#include "common/common_funcs.h"
// Generic function to get last error message.
// Call directly after the command or use the error num.
// This function might change the error code.
const char* GetLastErrorMsg() {
std::string GetLastErrorMsg() {
static const size_t buff_size = 255;
char err_str[buff_size];
#ifdef _WIN32
static __declspec(thread) char err_str[buff_size] = {};
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_str, buff_size, nullptr);
#else
static __thread char err_str[buff_size] = {};
// Thread safe (XSI-compliant)
strerror_r(errno, err_str, buff_size);
#endif
return err_str;
return std::string(err_str, buff_size);
}

View File

@@ -34,18 +34,6 @@ std::string ToUpper(std::string str) {
return str;
}
// faster than sscanf
bool AsciiToHex(const char* _szValue, u32& result) {
char* endptr = nullptr;
const u32 value = strtoul(_szValue, &endptr, 16);
if (!endptr || *endptr)
return false;
result = value;
return true;
}
// For Debugging. Read out an u8 array.
std::string ArrayToString(const u8* data, size_t size, int line_len, bool spaces) {
std::ostringstream oss;

View File

@@ -57,9 +57,6 @@ static bool TryParse(const std::string& str, N* const output) {
return false;
}
// TODO: kill this
bool AsciiToHex(const char* _szValue, u32& result);
std::string TabsToSpaces(int tab_size, const std::string& in);
void SplitString(const std::string& str, char delim, std::vector<std::string>& output);

View File

@@ -167,7 +167,7 @@ inline double swapd(double f) {
template <typename T, typename F>
struct swap_struct_t {
typedef swap_struct_t<T, F> swapped_t;
using swapped_t = swap_struct_t;
protected:
T value = T();
@@ -177,7 +177,7 @@ protected:
}
public:
T const swap() const {
T swap() const {
return swap(value);
}
swap_struct_t() = default;
@@ -185,39 +185,39 @@ public:
template <typename S>
swapped_t& operator=(const S& source) {
value = swap((T)source);
value = swap(static_cast<T>(source));
return *this;
}
operator s8() const {
return (s8)swap();
return static_cast<s8>(swap());
}
operator u8() const {
return (u8)swap();
return static_cast<u8>(swap());
}
operator s16() const {
return (s16)swap();
return static_cast<s16>(swap());
}
operator u16() const {
return (u16)swap();
return static_cast<u16>(swap());
}
operator s32() const {
return (s32)swap();
return static_cast<s32>(swap());
}
operator u32() const {
return (u32)swap();
return static_cast<u32>(swap());
}
operator s64() const {
return (s64)swap();
return static_cast<s64>(swap());
}
operator u64() const {
return (u64)swap();
return static_cast<u64>(swap());
}
operator float() const {
return (float)swap();
return static_cast<float>(swap());
}
operator double() const {
return (double)swap();
return static_cast<double>(swap());
}
// +v
@@ -253,7 +253,7 @@ public:
}
template <typename S>
swapped_t operator+(const S& i) const {
return swap() + (T)i;
return swap() + static_cast<T>(i);
}
// v - 5
swapped_t operator-(const swapped_t& i) const {
@@ -261,7 +261,7 @@ public:
}
template <typename S>
swapped_t operator-(const S& i) const {
return swap() - (T)i;
return swap() - static_cast<T>(i);
}
// v += 5
@@ -271,7 +271,7 @@ public:
}
template <typename S>
swapped_t& operator+=(const S& i) {
value = swap(swap() + (T)i);
value = swap(swap() + static_cast<T>(i));
return *this;
}
// v -= 5
@@ -281,7 +281,7 @@ public:
}
template <typename S>
swapped_t& operator-=(const S& i) {
value = swap(swap() - (T)i);
value = swap(swap() - static_cast<T>(i));
return *this;
}
@@ -541,7 +541,7 @@ S operator&(const S& i, const swap_struct_t<T, F> v) {
template <typename S, typename T, typename F>
S operator&(const swap_struct_t<T, F> v, const S& i) {
return (S)(v.swap() & i);
return static_cast<S>(v.swap() & i);
}
// Comparaison
@@ -606,51 +606,51 @@ struct swap_double_t {
};
#if COMMON_LITTLE_ENDIAN
typedef u32 u32_le;
typedef u16 u16_le;
typedef u64 u64_le;
using u16_le = u16;
using u32_le = u32;
using u64_le = u64;
typedef s32 s32_le;
typedef s16 s16_le;
typedef s64 s64_le;
using s16_le = s16;
using s32_le = s32;
using s64_le = s64;
typedef float float_le;
typedef double double_le;
using float_le = float;
using double_le = double;
typedef swap_struct_t<u64, swap_64_t<u64>> u64_be;
typedef swap_struct_t<s64, swap_64_t<s64>> s64_be;
using u64_be = swap_struct_t<u64, swap_64_t<u64>>;
using s64_be = swap_struct_t<s64, swap_64_t<s64>>;
typedef swap_struct_t<u32, swap_32_t<u32>> u32_be;
typedef swap_struct_t<s32, swap_32_t<s32>> s32_be;
using u32_be = swap_struct_t<u32, swap_32_t<u32>>;
using s32_be = swap_struct_t<s32, swap_32_t<s32>>;
typedef swap_struct_t<u16, swap_16_t<u16>> u16_be;
typedef swap_struct_t<s16, swap_16_t<s16>> s16_be;
using u16_be = swap_struct_t<u16, swap_16_t<u16>>;
using s16_be = swap_struct_t<s16, swap_16_t<s16>>;
typedef swap_struct_t<float, swap_float_t<float>> float_be;
typedef swap_struct_t<double, swap_double_t<double>> double_be;
using float_be = swap_struct_t<float, swap_float_t<float>>;
using double_be = swap_struct_t<double, swap_double_t<double>>;
#else
typedef swap_struct_t<u64, swap_64_t<u64>> u64_le;
typedef swap_struct_t<s64, swap_64_t<s64>> s64_le;
using u64_le = swap_struct_t<u64, swap_64_t<u64>>;
using s64_le = swap_struct_t<s64, swap_64_t<s64>>;
typedef swap_struct_t<u32, swap_32_t<u32>> u32_le;
typedef swap_struct_t<s32, swap_32_t<s32>> s32_le;
using u32_le = swap_struct_t<u32, swap_32_t<u32>>;
using s32_le = swap_struct_t<s32, swap_32_t<s32>>;
typedef swap_struct_t<u16, swap_16_t<u16>> u16_le;
typedef swap_struct_t<s16, swap_16_t<s16>> s16_le;
using u16_le = swap_struct_t<u16, swap_16_t<u16>>;
using s16_le = swap_struct_t<s16, swap_16_t<s16>>;
typedef swap_struct_t<float, swap_float_t<float>> float_le;
typedef swap_struct_t<double, swap_double_t<double>> double_le;
using float_le = swap_struct_t<float, swap_float_t<float>>;
using double_le = swap_struct_t<double, swap_double_t<double>>;
typedef u32 u32_be;
typedef u16 u16_be;
typedef u64 u64_be;
using u16_be = u16;
using u32_be = u32;
using u64_be = u64;
typedef s32 s32_be;
typedef s16 s16_be;
typedef s64 s64_be;
using s16_be = s16;
using s32_be = s32;
using s64_be = s64;
typedef float float_be;
typedef double double_be;
using float_be = float;
using double_be = double;
#endif

View File

@@ -104,6 +104,10 @@ public:
virtual void SetTlsAddress(VAddr address) = 0;
virtual u64 GetTPIDR_EL0() const = 0;
virtual void SetTPIDR_EL0(u64 value) = 0;
/**
* Saves the current CPU context
* @param ctx Thread context to save

View File

@@ -196,6 +196,14 @@ void ARM_Dynarmic::SetTlsAddress(u64 address) {
cb->tpidrro_el0 = address;
}
u64 ARM_Dynarmic::GetTPIDR_EL0() const {
return cb->tpidr_el0;
}
void ARM_Dynarmic::SetTPIDR_EL0(u64 value) {
cb->tpidr_el0 = value;
}
void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
ctx.cpu_registers = jit->GetRegisters();
ctx.sp = jit->GetSP();

View File

@@ -34,6 +34,8 @@ public:
void SetCPSR(u32 cpsr) override;
VAddr GetTlsAddress() const override;
void SetTlsAddress(VAddr address) override;
void SetTPIDR_EL0(u64 value) override;
u64 GetTPIDR_EL0() const override;
void SaveContext(ThreadContext& ctx) override;
void LoadContext(const ThreadContext& ctx) override;

View File

@@ -169,6 +169,16 @@ void ARM_Unicorn::SetTlsAddress(VAddr base) {
CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base));
}
u64 ARM_Unicorn::GetTPIDR_EL0() const {
u64 value{};
CHECKED(uc_reg_read(uc, UC_ARM64_REG_TPIDR_EL0, &value));
return value;
}
void ARM_Unicorn::SetTPIDR_EL0(u64 value) {
CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDR_EL0, &value));
}
void ARM_Unicorn::Run() {
if (GDBStub::IsServerEnabled()) {
ExecuteInstructions(std::max(4000000, 0));

View File

@@ -28,6 +28,8 @@ public:
void SetCPSR(u32 cpsr) override;
VAddr GetTlsAddress() const override;
void SetTlsAddress(VAddr address) override;
void SetTPIDR_EL0(u64 value) override;
u64 GetTPIDR_EL0() const override;
void SaveContext(ThreadContext& ctx) override;
void LoadContext(const ThreadContext& ctx) override;
void PrepareReschedule() override;

View File

@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <utility>
#include "common/logging/log.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/vfs_offset.h"
@@ -61,7 +64,7 @@ struct RomFSSuperblock {
};
static_assert(sizeof(RomFSSuperblock) == 0xE8, "RomFSSuperblock has incorrect size.");
NCA::NCA(VirtualFile file_) : file(file_) {
NCA::NCA(VirtualFile file_) : file(std::move(file_)) {
if (sizeof(NCAHeader) != file->ReadObject(&header))
LOG_CRITICAL(Loader, "File reader errored out during header read.");

View File

@@ -4,6 +4,11 @@
#pragma once
#include <array>
#include <memory>
#include <string>
#include <vector>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
@@ -48,7 +53,7 @@ struct NCAHeader {
};
static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size.");
inline bool IsDirectoryExeFS(std::shared_ptr<FileSys::VfsDirectory> pfs) {
inline bool IsDirectoryExeFS(const std::shared_ptr<VfsDirectory>& pfs) {
// According to switchbrew, an exefs must only contain these two files:
return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr;
}

View File

@@ -11,6 +11,11 @@
namespace FileSys {
bool PartitionFilesystem::Header::HasValidMagicValue() const {
return magic == Common::MakeMagic('H', 'F', 'S', '0') ||
magic == Common::MakeMagic('P', 'F', 'S', '0');
}
PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) {
// At least be as large as the header
if (file->GetSize() < sizeof(Header)) {
@@ -20,19 +25,17 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) {
// For cartridges, HFSs can get very large, so we need to calculate the size up to
// the actual content itself instead of just blindly reading in the entire file.
Header pfs_header;
if (sizeof(Header) != file->ReadObject(&pfs_header)) {
status = Loader::ResultStatus::Error;
return;
}
if (pfs_header.magic != Common::MakeMagic('H', 'F', 'S', '0') &&
pfs_header.magic != Common::MakeMagic('P', 'F', 'S', '0')) {
if (!pfs_header.HasValidMagicValue()) {
status = Loader::ResultStatus::ErrorInvalidFormat;
return;
}
bool is_hfs = pfs_header.magic == Common::MakeMagic('H', 'F', 'S', '0');
is_hfs = pfs_header.magic == Common::MakeMagic('H', 'F', 'S', '0');
size_t entry_size = is_hfs ? sizeof(HFSEntry) : sizeof(PFSEntry);
size_t metadata_size =
@@ -40,27 +43,13 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) {
// Actually read in now...
std::vector<u8> file_data = file->ReadBytes(metadata_size);
const size_t total_size = file_data.size();
if (file_data.size() != metadata_size) {
if (total_size != metadata_size) {
status = Loader::ResultStatus::Error;
return;
}
size_t total_size = file_data.size();
if (total_size < sizeof(Header)) {
status = Loader::ResultStatus::Error;
return;
}
memcpy(&pfs_header, file_data.data(), sizeof(Header));
if (pfs_header.magic != Common::MakeMagic('H', 'F', 'S', '0') &&
pfs_header.magic != Common::MakeMagic('P', 'F', 'S', '0')) {
status = Loader::ResultStatus::ErrorInvalidFormat;
return;
}
is_hfs = pfs_header.magic == Common::MakeMagic('H', 'F', 'S', '0');
size_t entries_offset = sizeof(Header);
size_t strtab_offset = entries_offset + (pfs_header.num_entries * entry_size);
content_offset = strtab_offset + pfs_header.strtab_size;

View File

@@ -42,6 +42,8 @@ private:
u32_le num_entries;
u32_le strtab_size;
INSERT_PADDING_BYTES(0x4);
bool HasValidMagicValue() const;
};
static_assert(sizeof(Header) == 0x10, "PFS/HFS header structure size is wrong");
@@ -73,11 +75,11 @@ private:
#pragma pack(pop)
Loader::ResultStatus status;
Loader::ResultStatus status{};
Header pfs_header;
bool is_hfs;
size_t content_offset;
Header pfs_header{};
bool is_hfs = false;
size_t content_offset = 0;
std::vector<VirtualFile> pfs_files;
std::vector<VirtualDir> pfs_dirs;

View File

@@ -11,7 +11,7 @@
namespace FileSys {
std::string SaveDataDescriptor::DebugInfo() {
std::string SaveDataDescriptor::DebugInfo() const {
return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}]",
static_cast<u8>(type), title_id, user_id[1], user_id[0], save_id);
}

View File

@@ -37,7 +37,7 @@ struct SaveDataDescriptor {
u64_le zero_2;
u64_le zero_3;
std::string DebugInfo();
std::string DebugInfo() const;
};
static_assert(sizeof(SaveDataDescriptor) == 0x40, "SaveDataDescriptor has incorrect size.");

View File

@@ -205,7 +205,7 @@ static Kernel::Thread* FindThreadById(int id) {
for (u32 core = 0; core < Core::NUM_CPU_CORES; core++) {
const auto& threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
for (auto& thread : threads) {
if (thread->GetThreadId() == id) {
if (thread->GetThreadId() == static_cast<u32>(id)) {
current_core = core;
return thread.get();
}
@@ -214,7 +214,7 @@ static Kernel::Thread* FindThreadById(int id) {
return nullptr;
}
static u64 RegRead(int id, Kernel::Thread* thread = nullptr) {
static u64 RegRead(std::size_t id, Kernel::Thread* thread = nullptr) {
if (!thread) {
return 0;
}
@@ -234,7 +234,7 @@ static u64 RegRead(int id, Kernel::Thread* thread = nullptr) {
}
}
static void RegWrite(int id, u64 val, Kernel::Thread* thread = nullptr) {
static void RegWrite(std::size_t id, u64 val, Kernel::Thread* thread = nullptr) {
if (!thread) {
return;
}
@@ -744,7 +744,7 @@ static bool IsDataAvailable() {
fd_set fd_socket;
FD_ZERO(&fd_socket);
FD_SET(gdbserver_socket, &fd_socket);
FD_SET(static_cast<u32>(gdbserver_socket), &fd_socket);
struct timeval t;
t.tv_sec = 0;
@@ -793,7 +793,7 @@ static void ReadRegisters() {
u8* bufptr = buffer;
for (int reg = 0; reg <= SP_REGISTER; reg++) {
for (u32 reg = 0; reg <= SP_REGISTER; reg++) {
LongToGdbHex(bufptr + reg * 16, RegRead(reg, current_thread));
}
@@ -807,7 +807,7 @@ static void ReadRegisters() {
bufptr += 8;
for (int reg = UC_ARM64_REG_Q0; reg <= UC_ARM64_REG_Q0 + 31; reg++) {
for (u32 reg = UC_ARM64_REG_Q0; reg <= UC_ARM64_REG_Q0 + 31; reg++) {
LongToGdbHex(bufptr + reg * 16, RegRead(reg, current_thread));
}
@@ -858,7 +858,7 @@ static void WriteRegisters() {
if (command_buffer[0] != 'G')
return SendReply("E01");
for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
for (u32 i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
if (reg <= SP_REGISTER) {
RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
} else if (reg == PC_REGISTER) {

View File

@@ -301,10 +301,6 @@ size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffe
return size;
}
size_t HLERequestContext::WriteBuffer(const std::vector<u8>& buffer, int buffer_index) const {
return WriteBuffer(buffer.data(), buffer.size());
}
size_t HLERequestContext::GetReadBufferSize(int buffer_index) const {
const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()};
return is_buffer_a ? BufferDescriptorA()[buffer_index].Size()

View File

@@ -5,8 +5,10 @@
#pragma once
#include <array>
#include <iterator>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
#include <boost/container/small_vector.hpp>
#include "common/common_types.h"
@@ -171,8 +173,25 @@ public:
/// Helper function to write a buffer using the appropriate buffer descriptor
size_t WriteBuffer(const void* buffer, size_t size, int buffer_index = 0) const;
/// Helper function to write a buffer using the appropriate buffer descriptor
size_t WriteBuffer(const std::vector<u8>& buffer, int buffer_index = 0) const;
/* Helper function to write a buffer using the appropriate buffer descriptor
*
* @tparam ContiguousContainer an arbitrary container that satisfies the
* ContiguousContainer concept in the C++ standard library.
*
* @param container The container to write the data of into a buffer.
* @param buffer_index The buffer in particular to write to.
*/
template <typename ContiguousContainer,
typename = std::enable_if_t<!std::is_pointer_v<ContiguousContainer>>>
size_t WriteBuffer(const ContiguousContainer& container, int buffer_index = 0) const {
using ContiguousType = typename ContiguousContainer::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>,
"Container to WriteBuffer must contain trivially copyable objects");
return WriteBuffer(std::data(container), std::size(container) * sizeof(ContiguousType),
buffer_index);
}
/// Helper function to get the size of the input buffer
size_t GetReadBufferSize(int buffer_index = 0) const;

View File

@@ -56,6 +56,8 @@ void Scheduler::SwitchContext(Thread* new_thread) {
if (previous_thread) {
previous_thread->last_running_ticks = CoreTiming::GetTicks();
cpu_core->SaveContext(previous_thread->context);
// Save the TPIDR_EL0 system register in case it was modified.
previous_thread->tpidr_el0 = cpu_core->GetTPIDR_EL0();
if (previous_thread->status == THREADSTATUS_RUNNING) {
// This is only the case when a reschedule is triggered without the current thread
@@ -87,6 +89,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
cpu_core->LoadContext(new_thread->context);
cpu_core->SetTlsAddress(new_thread->GetTLSAddress());
cpu_core->SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
cpu_core->ClearExclusiveState();
} else {
current_thread = nullptr;

View File

@@ -795,8 +795,9 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
return ERR_INVALID_HANDLE;
}
if (core == THREADPROCESSORID_DEFAULT) {
ASSERT(thread->owner_process->ideal_processor != THREADPROCESSORID_DEFAULT);
if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) {
ASSERT(thread->owner_process->ideal_processor !=
static_cast<u8>(THREADPROCESSORID_DEFAULT));
// Set the target CPU to the one specified in the process' exheader.
core = thread->owner_process->ideal_processor;
mask = 1ull << core;
@@ -811,7 +812,7 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
if (core == OnlyChangeMask) {
core = thread->ideal_core;
} else if (core >= Core::NUM_CPU_CORES && core != -1) {
} else if (core >= Core::NUM_CPU_CORES && core != static_cast<u32>(-1)) {
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidProcessorId);
}

View File

@@ -313,6 +313,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
thread->status = THREADSTATUS_DORMANT;
thread->entry_point = entry_point;
thread->stack_top = stack_top;
thread->tpidr_el0 = 0;
thread->nominal_priority = thread->current_priority = priority;
thread->last_running_ticks = CoreTiming::GetTicks();
thread->processor_id = processor_id;

View File

@@ -182,6 +182,14 @@ public:
return tls_address;
}
/*
* Returns the value of the TPIDR_EL0 Read/Write system register for this thread.
* @returns The value of the TPIDR_EL0 register.
*/
u64 GetTPIDR_EL0() const {
return tpidr_el0;
}
/*
* Returns the address of the current thread's command buffer, located in the TLS.
* @returns VAddr of the thread's command buffer.
@@ -213,6 +221,7 @@ public:
s32 processor_id;
VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread
u64 tpidr_el0; ///< TPIDR_EL0 read/write system register.
SharedPtr<Process> owner_process; ///< Process that owns this thread

View File

@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <array>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/acc/acc.h"
@@ -24,18 +25,17 @@ struct UserData {
static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size");
struct ProfileBase {
u8 user_id[0x10];
u128 user_id;
u64 timestamp;
u8 username[0x20];
std::array<u8, 0x20> username;
};
static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size");
using Uid = std::array<u64, 2>;
static constexpr Uid DEFAULT_USER_ID{0x10ull, 0x20ull};
static constexpr u128 DEFAULT_USER_ID{1ull, 0ull};
class IProfile final : public ServiceFramework<IProfile> {
public:
IProfile() : ServiceFramework("IProfile") {
IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) {
static const FunctionInfo functions[] = {
{0, nullptr, "Get"},
{1, &IProfile::GetBase, "GetBase"},
@@ -48,11 +48,18 @@ public:
private:
void GetBase(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
// TODO(Subv): Retrieve this information from somewhere.
ProfileBase profile_base{};
profile_base.user_id = user_id;
profile_base.username = {'y', 'u', 'z', 'u'};
IPC::ResponseBuilder rb{ctx, 16};
rb.Push(RESULT_SUCCESS);
rb.PushRaw(profile_base);
}
u128 user_id; ///< The user id this profile refers to.
};
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
@@ -95,25 +102,29 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID};
ctx.WriteBuffer(user_ids.data(), user_ids.size());
// TODO(Subv): There is only one user for now.
const std::vector<u128> user_ids = {DEFAULT_USER_ID};
ctx.WriteBuffer(user_ids.data(), user_ids.size() * sizeof(u128));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID};
ctx.WriteBuffer(user_ids.data(), user_ids.size());
// TODO(Subv): There is only one user for now.
const std::vector<u128> user_ids = {DEFAULT_USER_ID};
ctx.WriteBuffer(user_ids.data(), user_ids.size() * sizeof(u128));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
u128 user_id = rp.PopRaw<u128>();
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IProfile>();
LOG_DEBUG(Service_ACC, "called");
rb.PushIpcInterface<IProfile>(user_id);
LOG_DEBUG(Service_ACC, "called user_id=0x{:016X}{:016X}", user_id[1], user_id[0]);
}
void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {

View File

@@ -12,7 +12,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
explicit Interface(std::shared_ptr<Module> module, const char* name);
void GetUserExistence(Kernel::HLERequestContext& ctx);
void ListAllUsers(Kernel::HLERequestContext& ctx);

View File

@@ -72,7 +72,7 @@ public:
class ISelfController final : public ServiceFramework<ISelfController> {
public:
ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
explicit ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
private:
void SetFocusHandlingMode(Kernel::HLERequestContext& ctx);

View File

@@ -12,7 +12,7 @@ namespace Service::AM {
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
public:
ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
: ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)) {
static const FunctionInfo functions[] = {
{0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},

View File

@@ -17,7 +17,7 @@ namespace AM {
class AppletAE final : public ServiceFramework<AppletAE> {
public:
AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
~AppletAE() = default;
private:

View File

@@ -12,7 +12,7 @@ namespace Service::AM {
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
public:
IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
: ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)) {
static const FunctionInfo functions[] = {
{0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"},

View File

@@ -17,7 +17,7 @@ namespace AM {
class AppletOE final : public ServiceFramework<AppletOE> {
public:
AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
~AppletOE() = default;
private:

View File

@@ -10,7 +10,7 @@ namespace Service::APM {
class APM final : public ServiceFramework<APM> {
public:
APM(std::shared_ptr<Module> apm, const char* name);
explicit APM(std::shared_ptr<Module> apm, const char* name);
~APM() = default;
private:

View File

@@ -168,7 +168,7 @@ void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const std::string audio_interface = "AudioInterface";
ctx.WriteBuffer(audio_interface.c_str(), audio_interface.size());
ctx.WriteBuffer(audio_interface);
IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);

View File

@@ -17,7 +17,7 @@ constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 200)};
class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
public:
IAudioRenderer(AudioRendererParameter audren_params)
explicit IAudioRenderer(AudioRendererParameter audren_params)
: ServiceFramework("IAudioRenderer"), worker_params(audren_params) {
static const FunctionInfo functions[] = {
{0, nullptr, "GetAudioRendererSampleRate"},
@@ -176,7 +176,7 @@ private:
struct UpdateDataHeader {
UpdateDataHeader() {}
UpdateDataHeader(const AudioRendererParameter& config) {
explicit UpdateDataHeader(const AudioRendererParameter& config) {
revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
behavior_size = 0xb0;
memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
@@ -299,7 +299,7 @@ private:
IPC::RequestParser rp{ctx};
const std::string audio_interface = "AudioInterface";
ctx.WriteBuffer(audio_interface.c_str(), audio_interface.size());
ctx.WriteBuffer(audio_interface);
IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);
rb.Push(RESULT_SUCCESS);
@@ -324,7 +324,7 @@ private:
IPC::RequestParser rp{ctx};
const std::string audio_interface = "AudioDevice";
ctx.WriteBuffer(audio_interface.c_str(), audio_interface.size());
ctx.WriteBuffer(audio_interface);
IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);
rb.Push(RESULT_SUCCESS);

View File

@@ -12,7 +12,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
explicit Interface(std::shared_ptr<Module> module, const char* name);
void CreateBcatService(Kernel::HLERequestContext& ctx);

View File

@@ -12,7 +12,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
explicit Interface(std::shared_ptr<Module> module, const char* name);
void ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx);
void ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx);

View File

@@ -2,7 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma optimize("", off)
#include <utility>
#include "common/assert.h"
#include "common/file_util.h"
@@ -25,14 +25,14 @@ constexpr u64 EMULATED_SD_REPORTED_SIZE = 32000000000;
static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base,
const std::string& dir_name) {
if (dir_name == "." || dir_name == "" || dir_name == "/" || dir_name == "\\")
if (dir_name.empty() || dir_name == "." || dir_name == "/" || dir_name == "\\")
return base;
return base->GetDirectoryRelative(dir_name);
}
VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_)
: backing(backing_) {}
: backing(std::move(backing_)) {}
std::string VfsDirectoryServiceWrapper::GetName() const {
return backing->GetName();
@@ -193,6 +193,10 @@ ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType(
if (dir == nullptr)
return FileSys::ERROR_PATH_NOT_FOUND;
auto filename = FileUtil::GetFilename(path);
// TODO(Subv): Some games use the '/' path, find out what this means.
if (filename.empty())
return MakeResult(FileSys::EntryType::Directory);
if (dir->GetFile(filename) != nullptr)
return MakeResult(FileSys::EntryType::File);
if (dir->GetSubdirectory(filename) != nullptr)

View File

@@ -3,6 +3,14 @@
// Refer to the license.txt file included.
#include <cinttypes>
#include <cstring>
#include <iterator>
#include <string>
#include <utility>
#include <vector>
#include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/core.h"
@@ -26,7 +34,7 @@ enum class StorageId : u8 {
class IStorage final : public ServiceFramework<IStorage> {
public:
IStorage(FileSys::VirtualFile backend_)
explicit IStorage(FileSys::VirtualFile backend_)
: ServiceFramework("IStorage"), backend(std::move(backend_)) {
static const FunctionInfo functions[] = {
{0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"},
@@ -133,19 +141,19 @@ private:
return;
}
std::vector<u8> data = ctx.ReadBuffer();
std::vector<u8> actual_data(length);
const std::vector<u8> data = ctx.ReadBuffer();
ASSERT_MSG(
data.size() <= length,
static_cast<s64>(data.size()) <= length,
"Attempting to write more data than requested (requested={:016X}, actual={:016X}).",
length, data.size());
std::copy(data.begin(), data.end(), actual_data.begin());
// Write the data to the Storage backend
auto written = backend->WriteBytes(data, offset);
const auto write_size =
static_cast<std::size_t>(std::distance(data.begin(), data.begin() + length));
const std::size_t written = backend->Write(data.data(), write_size, offset);
ASSERT_MSG(written == length,
ASSERT_MSG(static_cast<s64>(written) == length,
"Could not write all bytes to file (requested={:016X}, actual={:016X}).", length,
written);
@@ -223,23 +231,20 @@ private:
LOG_DEBUG(Service_FS, "called, unk=0x{:X}", unk);
// Calculate how many entries we can fit in the output buffer
u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry);
const u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry);
// Cap at total number of entries.
u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index);
const u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index);
// Read the data from the Directory backend
std::vector<FileSys::Entry> entry_data(entries.begin() + next_entry_index,
entries.begin() + next_entry_index + actual_entries);
// Determine data start and end
const auto* begin = reinterpret_cast<u8*>(entries.data() + next_entry_index);
const auto* end = reinterpret_cast<u8*>(entries.data() + next_entry_index + actual_entries);
const auto range_size = static_cast<std::size_t>(std::distance(begin, end));
next_entry_index += actual_entries;
// Convert the data into a byte array
std::vector<u8> output(entry_data.size() * sizeof(FileSys::Entry));
std::memcpy(output.data(), entry_data.data(), output.size());
// Write the data to memory
ctx.WriteBuffer(output);
ctx.WriteBuffer(begin, range_size);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);

View File

@@ -12,7 +12,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
explicit Interface(std::shared_ptr<Module> module, const char* name);
void CreateFriendService(Kernel::HLERequestContext& ctx);

View File

@@ -85,8 +85,7 @@ private:
controller_header.left_color_buttons = JOYCON_BUTTONS_NEON_BLUE;
for (size_t controller = 0; controller < mem.controllers.size(); controller++) {
for (int index = 0; index < HID_NUM_LAYOUTS; index++) {
ControllerLayout& layout = mem.controllers[controller].layouts[index];
for (auto& layout : mem.controllers[controller].layouts) {
layout.header.num_entries = HID_NUM_ENTRIES;
layout.header.max_entry_index = HID_NUM_ENTRIES - 1;
@@ -213,8 +212,7 @@ private:
keyboard.entries[curr_keyboard_entry].timestamp_2 = keyboard_sample_counter;
// TODO(shinyquagsire23): Figure out what any of these are
for (size_t i = 0; i < mem.unk_input_1.size(); i++) {
UnkInput1& input = mem.unk_input_1[i];
for (auto& input : mem.unk_input_1) {
const u64 last_input_entry = input.header.latest_entry;
const u64 curr_input_entry = (input.header.latest_entry + 1) % input.entries.size();
const u64 input_sample_counter = input.entries[last_input_entry].timestamp + 1;
@@ -228,9 +226,7 @@ private:
input.entries[curr_input_entry].timestamp_2 = input_sample_counter;
}
for (size_t i = 0; i < mem.unk_input_2.size(); i++) {
UnkInput2& input = mem.unk_input_2[i];
for (auto& input : mem.unk_input_2) {
input.header.timestamp_ticks = timestamp;
input.header.num_entries = 17;
input.header.latest_entry = 0;

View File

@@ -380,7 +380,7 @@ static_assert(sizeof(ControllerLayout) == 0x350,
struct Controller {
ControllerHeader header;
std::array<ControllerLayout, 7> layouts;
std::array<ControllerLayout, HID_NUM_LAYOUTS> layouts;
std::array<u8, 0x2a70> unk_1;
ControllerMAC mac_left;
ControllerMAC mac_right;

View File

@@ -12,7 +12,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
explicit Interface(std::shared_ptr<Module> module, const char* name);
void CreateUserInterface(Kernel::HLERequestContext& ctx);

View File

@@ -12,7 +12,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
explicit Interface(std::shared_ptr<Module> module, const char* name);
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);

View File

@@ -119,7 +119,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for
LOG_DEBUG(Service_NS, "called, language_code=%lx", language_code);
LOG_DEBUG(Service_NS, "called, language_code={:X}", language_code);
IPC::ResponseBuilder rb{ctx, 4};
std::vector<u32> font_codes;
std::vector<u32> font_offsets;
@@ -132,9 +132,9 @@ void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) {
font_sizes.push_back(SHARED_FONT_REGIONS[i].size);
}
ctx.WriteBuffer(font_codes.data(), font_codes.size(), 0);
ctx.WriteBuffer(font_offsets.data(), font_offsets.size(), 1);
ctx.WriteBuffer(font_sizes.data(), font_sizes.size(), 2);
ctx.WriteBuffer(font_codes, 0);
ctx.WriteBuffer(font_offsets, 1);
ctx.WriteBuffer(font_sizes, 2);
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(static_cast<u8>(LoadState::Done)); // Fonts Loaded

View File

@@ -17,7 +17,7 @@ class nvmap;
class nvdisp_disp0 final : public nvdevice {
public:
nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev) : nvdevice(), nvmap_dev(std::move(nvmap_dev)) {}
explicit nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {}
~nvdisp_disp0() = default;
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;

View File

@@ -18,7 +18,7 @@ class nvmap;
class nvhost_as_gpu final : public nvdevice {
public:
nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {}
explicit nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {}
~nvhost_as_gpu() override = default;
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;

View File

@@ -18,7 +18,7 @@ constexpr u32 NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO(0x8);
class nvhost_gpu final : public nvdevice {
public:
nvhost_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {}
explicit nvhost_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {}
~nvhost_gpu() override = default;
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;

View File

@@ -23,15 +23,10 @@ constexpr u64 frame_ticks = static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / SCREE
NVFlinger::NVFlinger() {
// Add the different displays to the list of displays.
Display default_{0, "Default"};
Display external{1, "External"};
Display edid{2, "Edid"};
Display internal{3, "Internal"};
displays.emplace_back(default_);
displays.emplace_back(external);
displays.emplace_back(edid);
displays.emplace_back(internal);
displays.emplace_back(0, "Default");
displays.emplace_back(1, "External");
displays.emplace_back(2, "Edid");
displays.emplace_back(3, "Internal");
// Schedule the screen composition events
composition_event =

View File

@@ -12,7 +12,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
explicit Interface(std::shared_ptr<Module> module, const char* name);
void CreateService(Kernel::HLERequestContext& ctx);
void CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx);

View File

@@ -31,7 +31,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
LanguageCode::ZH_HANS,
LanguageCode::ZH_HANT,
}};
ctx.WriteBuffer(available_language_codes.data(), available_language_codes.size());
ctx.WriteBuffer(available_language_codes);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);

View File

@@ -22,7 +22,7 @@ namespace Service::SM {
/// Interface to "sm:" service
class SM final : public ServiceFramework<SM> {
public:
SM(std::shared_ptr<ServiceManager> service_manager);
explicit SM(std::shared_ptr<ServiceManager> service_manager);
~SM() override;
private:

View File

@@ -12,7 +12,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
explicit Interface(std::shared_ptr<Module> module, const char* name);
void GetRandomBytes(Kernel::HLERequestContext& ctx);

View File

@@ -57,7 +57,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> time, const char* name);
explicit Interface(std::shared_ptr<Module> time, const char* name);
void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx);
void GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx);

View File

@@ -579,7 +579,7 @@ private:
class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> {
public:
ISystemDisplayService() : ServiceFramework("ISystemDisplayService") {
explicit ISystemDisplayService() : ServiceFramework("ISystemDisplayService") {
static const FunctionInfo functions[] = {
{1200, nullptr, "GetZOrderCountMin"},
{1202, nullptr, "GetZOrderCountMax"},
@@ -777,7 +777,7 @@ private:
class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {
public:
IApplicationDisplayService(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
explicit IApplicationDisplayService(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
~IApplicationDisplayService() = default;
private:

View File

@@ -24,8 +24,8 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name,
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
explicit Interface(std::shared_ptr<Module> module, const char* name,
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger);
void GetDisplayService(Kernel::HLERequestContext& ctx);

View File

@@ -87,8 +87,8 @@ const char* GetFileTypeString(FileType type) {
* Get a loader for a file with a specific type
* @param file The file to load
* @param type The type of the file
* @param filename the file name (without path)
* @param filepath the file full path (with name)
* @param file the file to retrieve the loader for
* @param type the file type
* @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type
*/
static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileType type) {

View File

@@ -154,7 +154,7 @@ public:
/**
* Get the RomFS of the application
* Since the RomFS can be huge, we return a file reference instead of copying to a buffer
* @param file The file containing the RomFS
* @param dir The directory containing the RomFS
* @return ResultStatus result of function
*/
virtual ResultStatus ReadRomFS(FileSys::VirtualFile& dir) {
@@ -193,8 +193,8 @@ extern const std::initializer_list<Kernel::AddressMapping> default_address_mappi
/**
* Identifies a bootable file and return a suitable loader
* @param filename String filename of bootable file
* @return best loader for this file
* @param file The bootable file
* @return the best loader for this file
*/
std::unique_ptr<AppLoader> GetLoader(FileSys::VirtualFile file);

View File

@@ -82,7 +82,7 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
if (program_image.size() != PageAlignSize(nro_header.file_size))
return {};
for (int i = 0; i < nro_header.segments.size(); ++i) {
for (std::size_t i = 0; i < nro_header.segments.size(); ++i) {
codeset->segments[i].addr = nro_header.segments[i].offset;
codeset->segments[i].offset = nro_header.segments[i].offset;
codeset->segments[i].size = PageAlignSize(nro_header.segments[i].size);

View File

@@ -55,19 +55,20 @@ AppLoader_NSO::AppLoader_NSO(FileSys::VirtualFile file) : AppLoader(std::move(fi
FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& file) {
u32 magic = 0;
file->ReadObject(&magic);
if (Common::MakeMagic('N', 'S', 'O', '0') == magic) {
return FileType::NSO;
if (file->ReadObject(&magic) != sizeof(magic)) {
return FileType::Error;
}
return FileType::Error;
if (Common::MakeMagic('N', 'S', 'O', '0') != magic) {
return FileType::Error;
}
return FileType::NSO;
}
static std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data,
const NsoSegmentHeader& header) {
std::vector<u8> uncompressed_data;
uncompressed_data.resize(header.size);
std::vector<u8> uncompressed_data(header.size);
const int bytes_uncompressed = LZ4_decompress_safe(
reinterpret_cast<const char*>(compressed_data.data()),
reinterpret_cast<char*>(uncompressed_data.data()), compressed_data.size(), header.size);
@@ -80,8 +81,7 @@ static std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data,
static std::vector<u8> ReadSegment(FileUtil::IOFile& file, const NsoSegmentHeader& header,
size_t compressed_size) {
std::vector<u8> compressed_data;
compressed_data.resize(compressed_size);
std::vector<u8> compressed_data(compressed_size);
file.Seek(header.offset, SEEK_SET);
if (compressed_size != file.ReadBytes(compressed_data.data(), compressed_size)) {
@@ -113,7 +113,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) {
// Build program image
Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create("");
std::vector<u8> program_image;
for (int i = 0; i < nso_header.segments.size(); ++i) {
for (std::size_t i = 0; i < nso_header.segments.size(); ++i) {
const std::vector<u8> compressed_data =
file->ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset);
std::vector<u8> data = DecompressSegment(compressed_data, nso_header.segments[i]);

View File

@@ -216,7 +216,7 @@ public:
}
/// Returns a GLSL string representing the current state of the register
const std::string GetActiveString() {
std::string GetActiveString() {
declr_type.insert(active_type);
return GetPrefixString(active_type) + std::to_string(index) + '_' + suffix;
}
@@ -518,7 +518,7 @@ public:
private:
/// Build GLSL conversion function, e.g. floatBitsToInt, intBitsToFloat, etc.
const std::string GetGLSLConversionFunc(GLSLRegister::Type src, GLSLRegister::Type dest) const {
std::string GetGLSLConversionFunc(GLSLRegister::Type src, GLSLRegister::Type dest) const {
const std::string src_type = GLSLRegister::GetTypeString(src);
std::string dest_type = GLSLRegister::GetTypeString(dest);
dest_type[0] = toupper(dest_type[0]);