Compare commits

..

1 Commits

Author SHA1 Message Date
d8ea5704eb Android #12 2023-07-18 00:59:34 +00:00
87 changed files with 2565 additions and 2740 deletions

View File

@ -35,7 +35,7 @@ DESTDIR="$PWD/AppDir" ninja install
rm -vf AppDir/usr/bin/yuzu-cmd AppDir/usr/bin/yuzu-tester rm -vf AppDir/usr/bin/yuzu-cmd AppDir/usr/bin/yuzu-tester
# Download tools needed to build an AppImage # Download tools needed to build an AppImage
wget -nc https://raw.githubusercontent.com/yuzu-emu/ext-linux-bin/main/appimage/deploy-linux.sh wget -nc https://raw.githubusercontent.com/yuzu-emu/ext-linux-bin/main/gcc/deploy-linux.sh
wget -nc https://raw.githubusercontent.com/yuzu-emu/AppImageKit-checkrt/old/AppRun.sh wget -nc https://raw.githubusercontent.com/yuzu-emu/AppImageKit-checkrt/old/AppRun.sh
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/exec-x86_64.so wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/exec-x86_64.so
# Set executable bit # Set executable bit

View File

@ -12,7 +12,7 @@ steps:
inputs: inputs:
targetType: 'filePath' targetType: 'filePath'
filePath: './.ci/scripts/windows/install-vulkan-sdk.ps1' filePath: './.ci/scripts/windows/install-vulkan-sdk.ps1'
- script: refreshenv && glslangValidator --version && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DYUZU_ENABLE_LTO=ON -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd .. - script: refreshenv && glslangValidator --version && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DYUZU_ENABLE_LTO=ON -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
displayName: 'Configure CMake' displayName: 'Configure CMake'
- task: MSBuild@1 - task: MSBuild@1
displayName: 'Build' displayName: 'Build'

View File

@ -289,7 +289,7 @@ find_package(Boost 1.79.0 REQUIRED context)
find_package(enet 1.3 MODULE) find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED) find_package(fmt 9 REQUIRED)
find_package(inih 52 MODULE COMPONENTS INIReader) find_package(inih 52 MODULE COMPONENTS INIReader)
find_package(LLVM 17 MODULE COMPONENTS Demangle) find_package(LLVM MODULE COMPONENTS Demangle)
find_package(lz4 REQUIRED) find_package(lz4 REQUIRED)
find_package(nlohmann_json 3.8 REQUIRED) find_package(nlohmann_json 3.8 REQUIRED)
find_package(Opus 1.3 MODULE) find_package(Opus 1.3 MODULE)

View File

@ -20,7 +20,9 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <numeric>
#include <utility> #include <utility>
#include <vector>
using namespace llvm; using namespace llvm;
using namespace llvm::itanium_demangle; using namespace llvm::itanium_demangle;
@ -79,8 +81,8 @@ struct DumpVisitor {
} }
void printStr(const char *S) { fprintf(stderr, "%s", S); } void printStr(const char *S) { fprintf(stderr, "%s", S); }
void print(std::string_view SV) { void print(StringView SV) {
fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.data()); fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
} }
void print(const Node *N) { void print(const Node *N) {
if (N) if (N)
@ -88,6 +90,14 @@ struct DumpVisitor {
else else
printStr("<null>"); printStr("<null>");
} }
void print(NodeOrString NS) {
if (NS.isNode())
print(NS.asNode());
else if (NS.isString())
print(NS.asString());
else
printStr("NodeOrString()");
}
void print(NodeArray A) { void print(NodeArray A) {
++Depth; ++Depth;
printStr("{"); printStr("{");
@ -106,11 +116,13 @@ struct DumpVisitor {
// Overload used when T is exactly 'bool', not merely convertible to 'bool'. // Overload used when T is exactly 'bool', not merely convertible to 'bool'.
void print(bool B) { printStr(B ? "true" : "false"); } void print(bool B) { printStr(B ? "true" : "false"); }
template <class T> std::enable_if_t<std::is_unsigned<T>::value> print(T N) { template <class T>
typename std::enable_if<std::is_unsigned<T>::value>::type print(T N) {
fprintf(stderr, "%llu", (unsigned long long)N); fprintf(stderr, "%llu", (unsigned long long)N);
} }
template <class T> std::enable_if_t<std::is_signed<T>::value> print(T N) { template <class T>
typename std::enable_if<std::is_signed<T>::value>::type print(T N) {
fprintf(stderr, "%lld", (long long)N); fprintf(stderr, "%lld", (long long)N);
} }
@ -173,50 +185,6 @@ struct DumpVisitor {
return printStr("TemplateParamKind::Template"); return printStr("TemplateParamKind::Template");
} }
} }
void print(Node::Prec P) {
switch (P) {
case Node::Prec::Primary:
return printStr("Node::Prec::Primary");
case Node::Prec::Postfix:
return printStr("Node::Prec::Postfix");
case Node::Prec::Unary:
return printStr("Node::Prec::Unary");
case Node::Prec::Cast:
return printStr("Node::Prec::Cast");
case Node::Prec::PtrMem:
return printStr("Node::Prec::PtrMem");
case Node::Prec::Multiplicative:
return printStr("Node::Prec::Multiplicative");
case Node::Prec::Additive:
return printStr("Node::Prec::Additive");
case Node::Prec::Shift:
return printStr("Node::Prec::Shift");
case Node::Prec::Spaceship:
return printStr("Node::Prec::Spaceship");
case Node::Prec::Relational:
return printStr("Node::Prec::Relational");
case Node::Prec::Equality:
return printStr("Node::Prec::Equality");
case Node::Prec::And:
return printStr("Node::Prec::And");
case Node::Prec::Xor:
return printStr("Node::Prec::Xor");
case Node::Prec::Ior:
return printStr("Node::Prec::Ior");
case Node::Prec::AndIf:
return printStr("Node::Prec::AndIf");
case Node::Prec::OrIf:
return printStr("Node::Prec::OrIf");
case Node::Prec::Conditional:
return printStr("Node::Prec::Conditional");
case Node::Prec::Assign:
return printStr("Node::Prec::Assign");
case Node::Prec::Comma:
return printStr("Node::Prec::Comma");
case Node::Prec::Default:
return printStr("Node::Prec::Default");
}
}
void newLine() { void newLine() {
printStr("\n"); printStr("\n");
@ -366,21 +334,36 @@ public:
using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>; using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
char *llvm::itaniumDemangle(std::string_view MangledName) { char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
if (MangledName.empty()) size_t *N, int *Status) {
if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
if (Status)
*Status = demangle_invalid_args;
return nullptr; return nullptr;
}
int InternalStatus = demangle_success;
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
OutputStream S;
Demangler Parser(MangledName.data(),
MangledName.data() + MangledName.length());
Node *AST = Parser.parse(); Node *AST = Parser.parse();
if (!AST)
return nullptr;
OutputBuffer OB; if (AST == nullptr)
assert(Parser.ForwardTemplateRefs.empty()); InternalStatus = demangle_invalid_mangled_name;
AST->print(OB); else if (!initializeOutputStream(Buf, N, S, 1024))
OB += '\0'; InternalStatus = demangle_memory_alloc_failure;
return OB.getBuffer(); else {
assert(Parser.ForwardTemplateRefs.empty());
AST->print(S);
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
Buf = S.getBuffer();
}
if (Status)
*Status = InternalStatus;
return InternalStatus == demangle_success ? Buf : nullptr;
} }
ItaniumPartialDemangler::ItaniumPartialDemangler() ItaniumPartialDemangler::ItaniumPartialDemangler()
@ -413,12 +396,14 @@ bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
} }
static char *printNode(const Node *RootNode, char *Buf, size_t *N) { static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
OutputBuffer OB(Buf, N); OutputStream S;
RootNode->print(OB); if (!initializeOutputStream(Buf, N, S, 128))
OB += '\0'; return nullptr;
RootNode->print(S);
S += '\0';
if (N != nullptr) if (N != nullptr)
*N = OB.getCurrentPosition(); *N = S.getCurrentPosition();
return OB.getBuffer(); return S.getBuffer();
} }
char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const { char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
@ -432,8 +417,8 @@ char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
case Node::KAbiTagAttr: case Node::KAbiTagAttr:
Name = static_cast<const AbiTagAttr *>(Name)->Base; Name = static_cast<const AbiTagAttr *>(Name)->Base;
continue; continue;
case Node::KModuleEntity: case Node::KStdQualifiedName:
Name = static_cast<const ModuleEntity *>(Name)->Name; Name = static_cast<const StdQualifiedName *>(Name)->Child;
continue; continue;
case Node::KNestedName: case Node::KNestedName:
Name = static_cast<const NestedName *>(Name)->Name; Name = static_cast<const NestedName *>(Name)->Name;
@ -456,7 +441,9 @@ char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
return nullptr; return nullptr;
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName(); const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
OutputBuffer OB(Buf, N); OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
KeepGoingLocalFunction: KeepGoingLocalFunction:
while (true) { while (true) {
@ -471,27 +458,27 @@ char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
break; break;
} }
if (Name->getKind() == Node::KModuleEntity)
Name = static_cast<const ModuleEntity *>(Name)->Name;
switch (Name->getKind()) { switch (Name->getKind()) {
case Node::KStdQualifiedName:
S += "std";
break;
case Node::KNestedName: case Node::KNestedName:
static_cast<const NestedName *>(Name)->Qual->print(OB); static_cast<const NestedName *>(Name)->Qual->print(S);
break; break;
case Node::KLocalName: { case Node::KLocalName: {
auto *LN = static_cast<const LocalName *>(Name); auto *LN = static_cast<const LocalName *>(Name);
LN->Encoding->print(OB); LN->Encoding->print(S);
OB += "::"; S += "::";
Name = LN->Entity; Name = LN->Entity;
goto KeepGoingLocalFunction; goto KeepGoingLocalFunction;
} }
default: default:
break; break;
} }
OB += '\0'; S += '\0';
if (N != nullptr) if (N != nullptr)
*N = OB.getCurrentPosition(); *N = S.getCurrentPosition();
return OB.getBuffer(); return S.getBuffer();
} }
char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const { char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
@ -507,15 +494,17 @@ char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
return nullptr; return nullptr;
NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams(); NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
OutputBuffer OB(Buf, N); OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
OB += '('; S += '(';
Params.printWithComma(OB); Params.printWithComma(S);
OB += ')'; S += ')';
OB += '\0'; S += '\0';
if (N != nullptr) if (N != nullptr)
*N = OB.getCurrentPosition(); *N = S.getCurrentPosition();
return OB.getBuffer(); return S.getBuffer();
} }
char *ItaniumPartialDemangler::getFunctionReturnType( char *ItaniumPartialDemangler::getFunctionReturnType(
@ -523,16 +512,18 @@ char *ItaniumPartialDemangler::getFunctionReturnType(
if (!isFunction()) if (!isFunction())
return nullptr; return nullptr;
OutputBuffer OB(Buf, N); OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
if (const Node *Ret = if (const Node *Ret =
static_cast<const FunctionEncoding *>(RootNode)->getReturnType()) static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
Ret->print(OB); Ret->print(S);
OB += '\0'; S += '\0';
if (N != nullptr) if (N != nullptr)
*N = OB.getCurrentPosition(); *N = S.getCurrentPosition();
return OB.getBuffer(); return S.getBuffer();
} }
char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const { char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
@ -572,8 +563,8 @@ bool ItaniumPartialDemangler::isCtorOrDtor() const {
case Node::KNestedName: case Node::KNestedName:
N = static_cast<const NestedName *>(N)->Name; N = static_cast<const NestedName *>(N)->Name;
break; break;
case Node::KModuleEntity: case Node::KStdQualifiedName:
N = static_cast<const ModuleEntity *>(N)->Name; N = static_cast<const StdQualifiedName *>(N)->Child;
break; break;
} }
} }

View File

@ -12,7 +12,6 @@
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <string_view>
namespace llvm { namespace llvm {
/// This is a llvm local version of __cxa_demangle. Other than the name and /// This is a llvm local version of __cxa_demangle. Other than the name and
@ -30,10 +29,9 @@ enum : int {
demangle_success = 0, demangle_success = 0,
}; };
/// Returns a non-NULL pointer to a NUL-terminated C style string char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
/// that should be explicitly freed, if successful. Otherwise, may return int *status);
/// nullptr if mangled_name is not a valid mangling or is nullptr.
char *itaniumDemangle(std::string_view mangled_name);
enum MSDemangleFlags { enum MSDemangleFlags {
MSDF_None = 0, MSDF_None = 0,
@ -42,34 +40,10 @@ enum MSDemangleFlags {
MSDF_NoCallingConvention = 1 << 2, MSDF_NoCallingConvention = 1 << 2,
MSDF_NoReturnType = 1 << 3, MSDF_NoReturnType = 1 << 3,
MSDF_NoMemberType = 1 << 4, MSDF_NoMemberType = 1 << 4,
MSDF_NoVariableType = 1 << 5,
}; };
char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n,
/// Demangles the Microsoft symbol pointed at by mangled_name and returns it.
/// Returns a pointer to the start of a null-terminated demangled string on
/// success, or nullptr on error.
/// If n_read is non-null and demangling was successful, it receives how many
/// bytes of the input string were consumed.
/// status receives one of the demangle_ enum entries above if it's not nullptr.
/// Flags controls various details of the demangled representation.
char *microsoftDemangle(std::string_view mangled_name, size_t *n_read,
int *status, MSDemangleFlags Flags = MSDF_None); int *status, MSDemangleFlags Flags = MSDF_None);
// Demangles a Rust v0 mangled symbol.
char *rustDemangle(std::string_view MangledName);
// Demangles a D mangled symbol.
char *dlangDemangle(std::string_view MangledName);
/// Attempt to demangle a string using different demangling schemes.
/// The function uses heuristics to determine which demangling scheme to use.
/// \param MangledName - reference to string to demangle.
/// \returns - the demangled string, or a copy of the input string if no
/// demangling occurred.
std::string demangle(std::string_view MangledName);
bool nonMicrosoftDemangle(std::string_view MangledName, std::string &Result);
/// "Partial" demangler. This supports demangling a string into an AST /// "Partial" demangler. This supports demangling a string into an AST
/// (typically an intermediate stage in itaniumDemangle) and querying certain /// (typically an intermediate stage in itaniumDemangle) and querying certain
/// properties or partially printing the demangled name. /// properties or partially printing the demangled name.
@ -85,7 +59,7 @@ struct ItaniumPartialDemangler {
bool partialDemangle(const char *MangledName); bool partialDemangle(const char *MangledName);
/// Just print the entire mangled name into Buf. Buf and N behave like the /// Just print the entire mangled name into Buf. Buf and N behave like the
/// second and third parameters to __cxa_demangle. /// second and third parameters to itaniumDemangle.
char *finishDemangle(char *Buf, size_t *N) const; char *finishDemangle(char *Buf, size_t *N) const;
/// Get the base name of a function. This doesn't include trailing template /// Get the base name of a function. This doesn't include trailing template
@ -121,7 +95,6 @@ struct ItaniumPartialDemangler {
bool isSpecialName() const; bool isSpecialName() const;
~ItaniumPartialDemangler(); ~ItaniumPartialDemangler();
private: private:
void *RootNode; void *RootNode;
void *Context; void *Context;

View File

@ -13,8 +13,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_DEMANGLE_DEMANGLECONFIG_H #ifndef LLVM_DEMANGLE_COMPILER_H
#define LLVM_DEMANGLE_DEMANGLECONFIG_H #define LLVM_DEMANGLE_COMPILER_H
#ifndef __has_feature #ifndef __has_feature
#define __has_feature(x) 0 #define __has_feature(x) 0

File diff suppressed because it is too large Load Diff

View File

@ -1,96 +0,0 @@
//===--- ItaniumNodes.def ------------*- mode:c++;eval:(read-only-mode) -*-===//
// Do not edit! See README.txt.
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Define the demangler's node names
#ifndef NODE
#error Define NODE to handle nodes
#endif
NODE(NodeArrayNode)
NODE(DotSuffix)
NODE(VendorExtQualType)
NODE(QualType)
NODE(ConversionOperatorType)
NODE(PostfixQualifiedType)
NODE(ElaboratedTypeSpefType)
NODE(NameType)
NODE(AbiTagAttr)
NODE(EnableIfAttr)
NODE(ObjCProtoName)
NODE(PointerType)
NODE(ReferenceType)
NODE(PointerToMemberType)
NODE(ArrayType)
NODE(FunctionType)
NODE(NoexceptSpec)
NODE(DynamicExceptionSpec)
NODE(FunctionEncoding)
NODE(LiteralOperator)
NODE(SpecialName)
NODE(CtorVtableSpecialName)
NODE(QualifiedName)
NODE(NestedName)
NODE(LocalName)
NODE(ModuleName)
NODE(ModuleEntity)
NODE(VectorType)
NODE(PixelVectorType)
NODE(BinaryFPType)
NODE(BitIntType)
NODE(SyntheticTemplateParamName)
NODE(TypeTemplateParamDecl)
NODE(NonTypeTemplateParamDecl)
NODE(TemplateTemplateParamDecl)
NODE(TemplateParamPackDecl)
NODE(ParameterPack)
NODE(TemplateArgumentPack)
NODE(ParameterPackExpansion)
NODE(TemplateArgs)
NODE(ForwardTemplateReference)
NODE(NameWithTemplateArgs)
NODE(GlobalQualifiedName)
NODE(ExpandedSpecialSubstitution)
NODE(SpecialSubstitution)
NODE(CtorDtorName)
NODE(DtorName)
NODE(UnnamedTypeName)
NODE(ClosureTypeName)
NODE(StructuredBindingName)
NODE(BinaryExpr)
NODE(ArraySubscriptExpr)
NODE(PostfixExpr)
NODE(ConditionalExpr)
NODE(MemberExpr)
NODE(SubobjectExpr)
NODE(EnclosingExpr)
NODE(CastExpr)
NODE(SizeofParamPackExpr)
NODE(CallExpr)
NODE(NewExpr)
NODE(DeleteExpr)
NODE(PrefixExpr)
NODE(FunctionParam)
NODE(ConversionExpr)
NODE(PointerToMemberConversionExpr)
NODE(InitListExpr)
NODE(FoldExpr)
NODE(ThrowExpr)
NODE(BoolExpr)
NODE(StringLiteral)
NODE(LambdaExpr)
NODE(EnumLiteral)
NODE(IntegerLiteral)
NODE(FloatLiteral)
NODE(DoubleLiteral)
NODE(LongDoubleLiteral)
NODE(BracedExpr)
NODE(BracedRangeExpr)
#undef NODE

View File

@ -1,5 +1,5 @@
//===--- StringView.h ----------------*- mode:c++;eval:(read-only-mode) -*-===// //===--- StringView.h -------------------------------------------*- C++ -*-===//
// Do not edit! See README.txt. //
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information. // See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project // SPDX-FileCopyrightText: Part of the LLVM Project
@ -8,9 +8,6 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// FIXME: Use std::string_view instead when we support C++17. // FIXME: Use std::string_view instead when we support C++17.
// There are two copies of this file in the source tree. The one under
// libcxxabi is the original and the one under llvm is the copy. Use
// cp-to-llvm.sh to update the copy. See README.txt for more details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -18,6 +15,7 @@
#define DEMANGLE_STRINGVIEW_H #define DEMANGLE_STRINGVIEW_H
#include "DemangleConfig.h" #include "DemangleConfig.h"
#include <algorithm>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
@ -39,23 +37,29 @@ public:
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {} StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
StringView() : First(nullptr), Last(nullptr) {} StringView() : First(nullptr), Last(nullptr) {}
StringView substr(size_t Pos, size_t Len = npos) const { StringView substr(size_t From) const {
assert(Pos <= size()); return StringView(begin() + From, size() - From);
if (Len > size() - Pos)
Len = size() - Pos;
return StringView(begin() + Pos, Len);
} }
size_t find(char C, size_t From = 0) const { size_t find(char C, size_t From = 0) const {
size_t FindBegin = std::min(From, size());
// Avoid calling memchr with nullptr. // Avoid calling memchr with nullptr.
if (From < size()) { if (FindBegin < size()) {
// Just forward to memchr, which is faster than a hand-rolled loop. // Just forward to memchr, which is faster than a hand-rolled loop.
if (const void *P = ::memchr(First + From, C, size() - From)) if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
return size_t(static_cast<const char *>(P) - First); return size_t(static_cast<const char *>(P) - First);
} }
return npos; return npos;
} }
StringView substr(size_t From, size_t To) const {
if (To >= size())
To = size() - 1;
if (From >= size())
From = size() - 1;
return StringView(First + From, First + To);
}
StringView dropFront(size_t N = 1) const { StringView dropFront(size_t N = 1) const {
if (N >= size()) if (N >= size())
N = size(); N = size();
@ -102,7 +106,7 @@ public:
bool startsWith(StringView Str) const { bool startsWith(StringView Str) const {
if (Str.size() > size()) if (Str.size() > size())
return false; return false;
return std::strncmp(Str.begin(), begin(), Str.size()) == 0; return std::equal(Str.begin(), Str.end(), begin());
} }
const char &operator[](size_t Idx) const { return *(begin() + Idx); } const char &operator[](size_t Idx) const { return *(begin() + Idx); }
@ -115,7 +119,7 @@ public:
inline bool operator==(const StringView &LHS, const StringView &RHS) { inline bool operator==(const StringView &LHS, const StringView &RHS) {
return LHS.size() == RHS.size() && return LHS.size() == RHS.size() &&
std::strncmp(LHS.begin(), RHS.begin(), LHS.size()) == 0; std::equal(LHS.begin(), LHS.end(), RHS.begin());
} }
DEMANGLE_NAMESPACE_END DEMANGLE_NAMESPACE_END

View File

@ -1,39 +0,0 @@
//===--- StringViewExtras.h ----------*- mode:c++;eval:(read-only-mode) -*-===//
// Do not edit! See README.txt.
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// There are two copies of this file in the source tree. The one under
// libcxxabi is the original and the one under llvm is the copy. Use
// cp-to-llvm.sh to update the copy. See README.txt for more details.
//
//===----------------------------------------------------------------------===//
#ifndef DEMANGLE_STRINGVIEW_H
#define DEMANGLE_STRINGVIEW_H
#include "DemangleConfig.h"
#include <string_view>
DEMANGLE_NAMESPACE_BEGIN
inline bool starts_with(std::string_view self, char C) noexcept {
return !self.empty() && *self.begin() == C;
}
inline bool starts_with(std::string_view haystack,
std::string_view needle) noexcept {
if (needle.size() > haystack.size())
return false;
haystack.remove_suffix(haystack.size() - needle.size());
return haystack == needle;
}
DEMANGLE_NAMESPACE_END
#endif

View File

@ -1,5 +1,5 @@
//===--- Utility.h -------------------*- mode:c++;eval:(read-only-mode) -*-===// //===--- Utility.h ----------------------------------------------*- C++ -*-===//
// Do not edit! See README.txt. //
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information. // See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project // SPDX-FileCopyrightText: Part of the LLVM Project
@ -7,83 +7,70 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// Provide some utility classes for use in the demangler. // Provide some utility classes for use in the demangler(s).
// There are two copies of this file in the source tree. The one in libcxxabi
// is the original and the one in llvm is the copy. Use cp-to-llvm.sh to update
// the copy. See README.txt for more details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef DEMANGLE_UTILITY_H #ifndef DEMANGLE_UTILITY_H
#define DEMANGLE_UTILITY_H #define DEMANGLE_UTILITY_H
#include "DemangleConfig.h" #include "StringView.h"
#include <array>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <exception> #include <iterator>
#include <limits> #include <limits>
#include <string_view>
DEMANGLE_NAMESPACE_BEGIN DEMANGLE_NAMESPACE_BEGIN
// Stream that AST nodes write their string representation into after the AST // Stream that AST nodes write their string representation into after the AST
// has been parsed. // has been parsed.
class OutputBuffer { class OutputStream {
char *Buffer = nullptr; char *Buffer;
size_t CurrentPosition = 0; size_t CurrentPosition;
size_t BufferCapacity = 0; size_t BufferCapacity;
// Ensure there are at least N more positions in the buffer. // Ensure there is at least n more positions in buffer.
void grow(size_t N) { void grow(size_t N) {
size_t Need = N + CurrentPosition; if (N + CurrentPosition >= BufferCapacity) {
if (Need > BufferCapacity) {
// Reduce the number of reallocations, with a bit of hysteresis. The
// number here is chosen so the first allocation will more-than-likely not
// allocate more than 1K.
Need += 1024 - 32;
BufferCapacity *= 2; BufferCapacity *= 2;
if (BufferCapacity < Need) if (BufferCapacity < N + CurrentPosition)
BufferCapacity = Need; BufferCapacity = N + CurrentPosition;
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity)); Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
if (Buffer == nullptr) if (Buffer == nullptr)
std::terminate(); std::terminate();
} }
} }
OutputBuffer &writeUnsigned(uint64_t N, bool isNeg = false) { void writeUnsigned(uint64_t N, bool isNeg = false) {
std::array<char, 21> Temp; // Handle special case...
char *TempPtr = Temp.data() + Temp.size(); if (N == 0) {
*this << '0';
return;
}
// Output at least one character. char Temp[21];
do { char *TempPtr = std::end(Temp);
*--TempPtr = char('0' + N % 10);
while (N) {
*--TempPtr = '0' + char(N % 10);
N /= 10; N /= 10;
} while (N); }
// Add negative sign. // Add negative sign...
if (isNeg) if (isNeg)
*--TempPtr = '-'; *--TempPtr = '-';
this->operator<<(StringView(TempPtr, std::end(Temp)));
return operator+=(
std::string_view(TempPtr, Temp.data() + Temp.size() - TempPtr));
} }
public: public:
OutputBuffer(char *StartBuf, size_t Size) OutputStream(char *StartBuf, size_t Size)
: Buffer(StartBuf), BufferCapacity(Size) {} : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
OutputBuffer(char *StartBuf, size_t *SizePtr) OutputStream() = default;
: OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {} void reset(char *Buffer_, size_t BufferCapacity_) {
OutputBuffer() = default; CurrentPosition = 0;
// Non-copyable Buffer = Buffer_;
OutputBuffer(const OutputBuffer &) = delete; BufferCapacity = BufferCapacity_;
OutputBuffer &operator=(const OutputBuffer &) = delete;
operator std::string_view() const {
return std::string_view(Buffer, CurrentPosition);
} }
/// If a ParameterPackExpansion (or similar type) is encountered, the offset /// If a ParameterPackExpansion (or similar type) is encountered, the offset
@ -91,116 +78,115 @@ public:
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max(); unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
unsigned CurrentPackMax = std::numeric_limits<unsigned>::max(); unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
/// When zero, we're printing template args and '>' needs to be parenthesized. OutputStream &operator+=(StringView R) {
/// Use a counter so we can simply increment inside parentheses. size_t Size = R.size();
unsigned GtIsGt = 1; if (Size == 0)
return *this;
bool isGtInsideTemplateArgs() const { return GtIsGt == 0; } grow(Size);
std::memmove(Buffer + CurrentPosition, R.begin(), Size);
void printOpen(char Open = '(') { CurrentPosition += Size;
GtIsGt++;
*this += Open;
}
void printClose(char Close = ')') {
GtIsGt--;
*this += Close;
}
OutputBuffer &operator+=(std::string_view R) {
if (size_t Size = R.size()) {
grow(Size);
std::memcpy(Buffer + CurrentPosition, &*R.begin(), Size);
CurrentPosition += Size;
}
return *this; return *this;
} }
OutputBuffer &operator+=(char C) { OutputStream &operator+=(char C) {
grow(1); grow(1);
Buffer[CurrentPosition++] = C; Buffer[CurrentPosition++] = C;
return *this; return *this;
} }
OutputBuffer &prepend(std::string_view R) { OutputStream &operator<<(StringView R) { return (*this += R); }
size_t Size = R.size();
grow(Size); OutputStream &operator<<(char C) { return (*this += C); }
std::memmove(Buffer + Size, Buffer, CurrentPosition);
std::memcpy(Buffer, &*R.begin(), Size);
CurrentPosition += Size;
OutputStream &operator<<(long long N) {
if (N < 0)
writeUnsigned(static_cast<unsigned long long>(-N), true);
else
writeUnsigned(static_cast<unsigned long long>(N));
return *this; return *this;
} }
OutputBuffer &operator<<(std::string_view R) { return (*this += R); } OutputStream &operator<<(unsigned long long N) {
writeUnsigned(N, false);
OutputBuffer &operator<<(char C) { return (*this += C); } return *this;
OutputBuffer &operator<<(long long N) {
return writeUnsigned(static_cast<unsigned long long>(std::abs(N)), N < 0);
} }
OutputBuffer &operator<<(unsigned long long N) { OutputStream &operator<<(long N) {
return writeUnsigned(N, false);
}
OutputBuffer &operator<<(long N) {
return this->operator<<(static_cast<long long>(N)); return this->operator<<(static_cast<long long>(N));
} }
OutputBuffer &operator<<(unsigned long N) { OutputStream &operator<<(unsigned long N) {
return this->operator<<(static_cast<unsigned long long>(N)); return this->operator<<(static_cast<unsigned long long>(N));
} }
OutputBuffer &operator<<(int N) { OutputStream &operator<<(int N) {
return this->operator<<(static_cast<long long>(N)); return this->operator<<(static_cast<long long>(N));
} }
OutputBuffer &operator<<(unsigned int N) { OutputStream &operator<<(unsigned int N) {
return this->operator<<(static_cast<unsigned long long>(N)); return this->operator<<(static_cast<unsigned long long>(N));
} }
void insert(size_t Pos, const char *S, size_t N) {
assert(Pos <= CurrentPosition);
if (N == 0)
return;
grow(N);
std::memmove(Buffer + Pos + N, Buffer + Pos, CurrentPosition - Pos);
std::memcpy(Buffer + Pos, S, N);
CurrentPosition += N;
}
size_t getCurrentPosition() const { return CurrentPosition; } size_t getCurrentPosition() const { return CurrentPosition; }
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; } void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
char back() const { char back() const {
assert(CurrentPosition); return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
return Buffer[CurrentPosition - 1];
} }
bool empty() const { return CurrentPosition == 0; } bool empty() const { return CurrentPosition == 0; }
char *getBuffer() { return Buffer; } char *getBuffer() { return Buffer; }
char *getBufferEnd() { return Buffer + CurrentPosition - 1; } char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
size_t getBufferCapacity() const { return BufferCapacity; } size_t getBufferCapacity() { return BufferCapacity; }
}; };
template <class T> class ScopedOverride { template <class T> class SwapAndRestore {
T &Loc; T &Restore;
T Original; T OriginalValue;
bool ShouldRestore = true;
public: public:
ScopedOverride(T &Loc_) : ScopedOverride(Loc_, Loc_) {} SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
ScopedOverride(T &Loc_, T NewVal) : Loc(Loc_), Original(Loc_) { SwapAndRestore(T &Restore_, T NewVal)
Loc_ = std::move(NewVal); : Restore(Restore_), OriginalValue(Restore) {
Restore = std::move(NewVal);
}
~SwapAndRestore() {
if (ShouldRestore)
Restore = std::move(OriginalValue);
} }
~ScopedOverride() { Loc = std::move(Original); }
ScopedOverride(const ScopedOverride &) = delete; void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
ScopedOverride &operator=(const ScopedOverride &) = delete;
void restoreNow(bool Force) {
if (!Force && !ShouldRestore)
return;
Restore = std::move(OriginalValue);
ShouldRestore = false;
}
SwapAndRestore(const SwapAndRestore &) = delete;
SwapAndRestore &operator=(const SwapAndRestore &) = delete;
}; };
inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
size_t InitSize) {
size_t BufferSize;
if (Buf == nullptr) {
Buf = static_cast<char *>(std::malloc(InitSize));
if (Buf == nullptr)
return false;
BufferSize = InitSize;
} else
BufferSize = *N;
S.reset(Buf, BufferSize);
return true;
}
DEMANGLE_NAMESPACE_END DEMANGLE_NAMESPACE_END
#endif #endif

View File

@ -449,7 +449,7 @@ private:
loader->ReadTitle(entry.title); loader->ReadTitle(entry.title);
loader->ReadIcon(entry.icon); loader->ReadIcon(entry.icon);
if (loader->GetFileType() == Loader::FileType::NRO) { if (loader->GetFileType() == Loader::FileType::NRO) {
jauto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get()); jauto loader_nro = dynamic_cast<Loader::AppLoader_NRO*>(loader.get());
entry.isHomebrew = loader_nro->IsHomebrew(); entry.isHomebrew = loader_nro->IsHomebrew();
} else { } else {
entry.isHomebrew = false; entry.isHomebrew = false;

View File

@ -23,7 +23,7 @@ std::string DemangleSymbol(const std::string& mangled) {
SCOPE_EXIT({ std::free(demangled); }); SCOPE_EXIT({ std::free(demangled); });
if (is_itanium(mangled)) { if (is_itanium(mangled)) {
demangled = llvm::itaniumDemangle(mangled.c_str()); demangled = llvm::itaniumDemangle(mangled.c_str(), nullptr, nullptr, nullptr);
} }
if (!demangled) { if (!demangled) {

View File

@ -30,8 +30,8 @@ DetachedTasks::~DetachedTasks() {
void DetachedTasks::AddTask(std::function<void()> task) { void DetachedTasks::AddTask(std::function<void()> task) {
std::unique_lock lock{instance->mutex}; std::unique_lock lock{instance->mutex};
++instance->count; ++instance->count;
std::thread([task_{std::move(task)}]() { std::thread([task{std::move(task)}]() {
task_(); task();
std::unique_lock thread_lock{instance->mutex}; std::unique_lock thread_lock{instance->mutex};
--instance->count; --instance->count;
std::notify_all_at_thread_exit(instance->cv, std::move(thread_lock)); std::notify_all_at_thread_exit(instance->cv, std::move(thread_lock));

View File

@ -26,8 +26,7 @@ std::string GetTimeZoneString() {
std::string location_name; std::string location_name;
if (time_zone_index == 0) { // Auto if (time_zone_index == 0) { // Auto
#if __cpp_lib_chrono >= 201907L && !defined(MINGW) #if __cpp_lib_chrono >= 201907L
// Disabled for MinGW -- tzdb always returns Etc/UTC
try { try {
const struct std::chrono::tzdb& time_zone_data = std::chrono::get_tzdb(); const struct std::chrono::tzdb& time_zone_data = std::chrono::get_tzdb();
const std::chrono::time_zone* current_zone = time_zone_data.current_zone(); const std::chrono::time_zone* current_zone = time_zone_data.current_zone();

View File

@ -3,11 +3,10 @@
#pragma once #pragma once
#include <optional>
#include <string>
#include "common/common_types.h" #include "common/common_types.h"
#include <optional>
namespace Network { namespace Network {
/// Address families /// Address families

View File

@ -4,13 +4,13 @@
#include <chrono> #include <chrono>
#include <exception> #include <exception>
#include <iomanip> #include <iomanip>
#include <map>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <fmt/chrono.h> #include <fmt/chrono.h>
#include <fmt/core.h> #include <fmt/core.h>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h"
#include "common/time_zone.h" #include "common/time_zone.h"
namespace Common::TimeZone { namespace Common::TimeZone {
@ -33,29 +33,32 @@ std::string GetDefaultTimeZone() {
return "GMT"; return "GMT";
} }
// Results are not comparable to seconds since Epoch static std::string GetOsTimeZoneOffset() {
static std::time_t TmSpecToSeconds(const struct std::tm& spec) { const std::time_t t{std::time(nullptr)};
const int year = spec.tm_year - 1; // Years up to now const std::tm tm{*std::localtime(&t)};
const int leap_years = year / 4 - year / 100;
std::time_t cumulative = spec.tm_year; return fmt::format("{:%z}", tm);
cumulative = cumulative * 365 + leap_years + spec.tm_yday; // Years to days }
cumulative = cumulative * 24 + spec.tm_hour; // Days to hours
cumulative = cumulative * 60 + spec.tm_min; // Hours to minutes static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) {
cumulative = cumulative * 60 + spec.tm_sec; // Minutes to seconds try {
return cumulative; return std::stoi(timezone);
} catch (const std::invalid_argument&) {
LOG_CRITICAL(Common, "invalid_argument with {}!", timezone);
return 0;
} catch (const std::out_of_range&) {
LOG_CRITICAL(Common, "out_of_range with {}!", timezone);
return 0;
}
} }
std::chrono::seconds GetCurrentOffsetSeconds() { std::chrono::seconds GetCurrentOffsetSeconds() {
const std::time_t t{std::time(nullptr)}; const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())};
const std::tm local{*std::localtime(&t)};
const std::tm gmt{*std::gmtime(&t)};
// gmt_seconds is a different offset than time(nullptr) int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds
const auto gmt_seconds = TmSpecToSeconds(gmt); seconds += (offset % 100) * 60; // Convert minute component to seconds
const auto local_seconds = TmSpecToSeconds(local);
const auto seconds_offset = local_seconds - gmt_seconds;
return std::chrono::seconds{seconds_offset}; return std::chrono::seconds{seconds};
} }
// Key is [Hours * 100 + Minutes], multiplied by 100 if DST // Key is [Hours * 100 + Minutes], multiplied by 100 if DST
@ -68,6 +71,11 @@ const static std::map<s64, const char*> off_timezones = {
}; };
std::string FindSystemTimeZone() { std::string FindSystemTimeZone() {
#if defined(MINGW)
// MinGW has broken strftime -- https://sourceforge.net/p/mingw-w64/bugs/793/
// e.g. fmt::format("{:%z}") -- returns "Eastern Daylight Time" when it should be "-0400"
return timezones[0];
#else
const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count()); const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count());
const s64 minutes = seconds / 60; const s64 minutes = seconds / 60;
@ -89,6 +97,7 @@ std::string FindSystemTimeZone() {
} }
} }
return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours)); return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours));
#endif
} }
} // namespace Common::TimeZone } // namespace Common::TimeZone

View File

@ -876,7 +876,7 @@ elseif (APPLE)
elseif (WIN32) elseif (WIN32)
target_sources(core PRIVATE target_sources(core PRIVATE
hle/service/ssl/ssl_backend_schannel.cpp) hle/service/ssl/ssl_backend_schannel.cpp)
target_link_libraries(core PRIVATE crypt32 secur32) target_link_libraries(core PRIVATE secur32)
else() else()
target_sources(core PRIVATE target_sources(core PRIVATE
hle/service/ssl/ssl_backend_none.cpp) hle/service/ssl/ssl_backend_none.cpp)

View File

@ -346,11 +346,11 @@ void ARM_Dynarmic_32::RewindBreakpointInstruction() {
} }
ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_,
DynarmicExclusiveMonitor& exclusive_monitor_, ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_)
std::size_t core_index_)
: ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)), : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)),
cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_}, cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_},
exclusive_monitor{exclusive_monitor_}, null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {} exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)},
null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {}
ARM_Dynarmic_32::~ARM_Dynarmic_32() = default; ARM_Dynarmic_32::~ARM_Dynarmic_32() = default;

View File

@ -12,7 +12,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "common/hash.h" #include "common/hash.h"
#include "core/arm/arm_interface.h" #include "core/arm/arm_interface.h"
#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h" #include "core/arm/exclusive_monitor.h"
namespace Core::Memory { namespace Core::Memory {
class Memory; class Memory;
@ -28,8 +28,8 @@ class System;
class ARM_Dynarmic_32 final : public ARM_Interface { class ARM_Dynarmic_32 final : public ARM_Interface {
public: public:
ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_,
DynarmicExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); std::size_t core_index_);
~ARM_Dynarmic_32() override; ~ARM_Dynarmic_32() override;
void SetPC(u64 pc) override; void SetPC(u64 pc) override;

View File

@ -405,11 +405,11 @@ void ARM_Dynarmic_64::RewindBreakpointInstruction() {
} }
ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_,
DynarmicExclusiveMonitor& exclusive_monitor_, ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_)
std::size_t core_index_)
: ARM_Interface{system_, uses_wall_clock_}, : ARM_Interface{system_, uses_wall_clock_},
cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_}, cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_},
exclusive_monitor{exclusive_monitor_}, null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {} exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)},
null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {}
ARM_Dynarmic_64::~ARM_Dynarmic_64() = default; ARM_Dynarmic_64::~ARM_Dynarmic_64() = default;

View File

@ -11,7 +11,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "common/hash.h" #include "common/hash.h"
#include "core/arm/arm_interface.h" #include "core/arm/arm_interface.h"
#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h" #include "core/arm/exclusive_monitor.h"
namespace Core::Memory { namespace Core::Memory {
class Memory; class Memory;
@ -25,8 +25,8 @@ class System;
class ARM_Dynarmic_64 final : public ARM_Interface { class ARM_Dynarmic_64 final : public ARM_Interface {
public: public:
ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_,
DynarmicExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); std::size_t core_index_);
~ARM_Dynarmic_64() override; ~ARM_Dynarmic_64() override;
void SetPC(u64 pc) override; void SetPC(u64 pc) override;

View File

@ -6,6 +6,8 @@
#include <dynarmic/interface/exclusive_monitor.h> #include <dynarmic/interface/exclusive_monitor.h>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/arm/dynarmic/arm_dynarmic_32.h"
#include "core/arm/dynarmic/arm_dynarmic_64.h"
#include "core/arm/exclusive_monitor.h" #include "core/arm/exclusive_monitor.h"
namespace Core::Memory { namespace Core::Memory {
@ -14,9 +16,6 @@ class Memory;
namespace Core { namespace Core {
class ARM_Dynarmic_32;
class ARM_Dynarmic_64;
class DynarmicExclusiveMonitor final : public ExclusiveMonitor { class DynarmicExclusiveMonitor final : public ExclusiveMonitor {
public: public:
explicit DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count_); explicit DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count_);

View File

@ -880,14 +880,6 @@ const FileSys::ContentProvider& System::GetContentProvider() const {
return *impl->content_provider; return *impl->content_provider;
} }
FileSys::ContentProviderUnion& System::GetContentProviderUnion() {
return *impl->content_provider;
}
const FileSys::ContentProviderUnion& System::GetContentProviderUnion() const {
return *impl->content_provider;
}
Service::FileSystem::FileSystemController& System::GetFileSystemController() { Service::FileSystem::FileSystemController& System::GetFileSystemController() {
return impl->fs_controller; return impl->fs_controller;
} }

View File

@ -381,9 +381,6 @@ public:
[[nodiscard]] FileSys::ContentProvider& GetContentProvider(); [[nodiscard]] FileSys::ContentProvider& GetContentProvider();
[[nodiscard]] const FileSys::ContentProvider& GetContentProvider() const; [[nodiscard]] const FileSys::ContentProvider& GetContentProvider() const;
[[nodiscard]] FileSys::ContentProviderUnion& GetContentProviderUnion();
[[nodiscard]] const FileSys::ContentProviderUnion& GetContentProviderUnion() const;
[[nodiscard]] Service::FileSystem::FileSystemController& GetFileSystemController(); [[nodiscard]] Service::FileSystem::FileSystemController& GetFileSystemController();
[[nodiscard]] const Service::FileSystem::FileSystemController& GetFileSystemController() const; [[nodiscard]] const Service::FileSystem::FileSystemController& GetFileSystemController() const;

View File

@ -556,7 +556,7 @@ void GDBStub::HandleQuery(std::string_view command) {
} else { } else {
SendReply(fmt::format( SendReply(fmt::format(
"TextSeg={:x}", "TextSeg={:x}",
GetInteger(system.ApplicationProcess()->GetPageTable().GetCodeRegionStart()))); GetInteger(system.ApplicationProcess()->PageTable().GetCodeRegionStart())));
} }
} else if (command.starts_with("Xfer:libraries:read::")) { } else if (command.starts_with("Xfer:libraries:read::")) {
Loader::AppLoader::Modules modules; Loader::AppLoader::Modules modules;
@ -731,7 +731,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
std::string reply; std::string reply;
auto* process = system.ApplicationProcess(); auto* process = system.ApplicationProcess();
auto& page_table = process->GetPageTable(); auto& page_table = process->PageTable();
const char* commands = "Commands:\n" const char* commands = "Commands:\n"
" get fastmem\n" " get fastmem\n"

View File

@ -25,7 +25,7 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, KProcessAddres
m_owner = GetCurrentProcessPointer(m_kernel); m_owner = GetCurrentProcessPointer(m_kernel);
// Get the owner page table. // Get the owner page table.
auto& page_table = m_owner->GetPageTable(); auto& page_table = m_owner->PageTable();
// Construct the page group. // Construct the page group.
m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager()); m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager());
@ -53,7 +53,7 @@ void KCodeMemory::Finalize() {
// Unlock. // Unlock.
if (!m_is_mapped && !m_is_owner_mapped) { if (!m_is_mapped && !m_is_owner_mapped) {
const size_t size = m_page_group->GetNumPages() * PageSize; const size_t size = m_page_group->GetNumPages() * PageSize;
m_owner->GetPageTable().UnlockForCodeMemory(m_address, size, *m_page_group); m_owner->PageTable().UnlockForCodeMemory(m_address, size, *m_page_group);
} }
// Close the page group. // Close the page group.
@ -75,7 +75,7 @@ Result KCodeMemory::Map(KProcessAddress address, size_t size) {
R_UNLESS(!m_is_mapped, ResultInvalidState); R_UNLESS(!m_is_mapped, ResultInvalidState);
// Map the memory. // Map the memory.
R_TRY(GetCurrentProcess(m_kernel).GetPageTable().MapPageGroup( R_TRY(GetCurrentProcess(m_kernel).PageTable().MapPageGroup(
address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite)); address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite));
// Mark ourselves as mapped. // Mark ourselves as mapped.
@ -92,8 +92,8 @@ Result KCodeMemory::Unmap(KProcessAddress address, size_t size) {
KScopedLightLock lk(m_lock); KScopedLightLock lk(m_lock);
// Unmap the memory. // Unmap the memory.
R_TRY(GetCurrentProcess(m_kernel).GetPageTable().UnmapPageGroup(address, *m_page_group, R_TRY(GetCurrentProcess(m_kernel).PageTable().UnmapPageGroup(address, *m_page_group,
KMemoryState::CodeOut)); KMemoryState::CodeOut));
// Mark ourselves as unmapped. // Mark ourselves as unmapped.
m_is_mapped = false; m_is_mapped = false;
@ -126,8 +126,8 @@ Result KCodeMemory::MapToOwner(KProcessAddress address, size_t size, Svc::Memory
} }
// Map the memory. // Map the memory.
R_TRY(m_owner->GetPageTable().MapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode, R_TRY(m_owner->PageTable().MapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode,
k_perm)); k_perm));
// Mark ourselves as mapped. // Mark ourselves as mapped.
m_is_owner_mapped = true; m_is_owner_mapped = true;
@ -143,8 +143,7 @@ Result KCodeMemory::UnmapFromOwner(KProcessAddress address, size_t size) {
KScopedLightLock lk(m_lock); KScopedLightLock lk(m_lock);
// Unmap the memory. // Unmap the memory.
R_TRY(m_owner->GetPageTable().UnmapPageGroup(address, *m_page_group, R_TRY(m_owner->PageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode));
KMemoryState::GeneratedCode));
// Mark ourselves as unmapped. // Mark ourselves as unmapped.
m_is_owner_mapped = false; m_is_owner_mapped = false;

View File

@ -388,6 +388,39 @@ public:
constexpr size_t GetHeapSize() const { constexpr size_t GetHeapSize() const {
return m_current_heap_end - m_heap_region_start; return m_current_heap_end - m_heap_region_start;
} }
constexpr bool IsInsideAddressSpace(KProcessAddress address, size_t size) const {
return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1;
}
constexpr bool IsOutsideAliasRegion(KProcessAddress address, size_t size) const {
return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1;
}
constexpr bool IsOutsideStackRegion(KProcessAddress address, size_t size) const {
return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1;
}
constexpr bool IsInvalidRegion(KProcessAddress address, size_t size) const {
return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1;
}
constexpr bool IsInsideHeapRegion(KProcessAddress address, size_t size) const {
return address + size > m_heap_region_start && m_heap_region_end > address;
}
constexpr bool IsInsideAliasRegion(KProcessAddress address, size_t size) const {
return address + size > m_alias_region_start && m_alias_region_end > address;
}
constexpr bool IsOutsideASLRRegion(KProcessAddress address, size_t size) const {
if (IsInvalidRegion(address, size)) {
return true;
}
if (IsInsideHeapRegion(address, size)) {
return true;
}
if (IsInsideAliasRegion(address, size)) {
return true;
}
return {};
}
constexpr bool IsInsideASLRRegion(KProcessAddress address, size_t size) const {
return !IsOutsideASLRRegion(address, size);
}
constexpr size_t GetNumGuardPages() const { constexpr size_t GetNumGuardPages() const {
return IsKernel() ? 1 : 4; return IsKernel() ? 1 : 4;
} }
@ -403,14 +436,6 @@ public:
return m_address_space_start <= addr && addr < addr + size && return m_address_space_start <= addr && addr < addr + size &&
addr + size - 1 <= m_address_space_end - 1; addr + size - 1 <= m_address_space_end - 1;
} }
constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const {
return this->Contains(addr, size) && m_alias_region_start <= addr &&
addr + size - 1 <= m_alias_region_end - 1;
}
constexpr bool IsInHeapRegion(KProcessAddress addr, size_t size) const {
return this->Contains(addr, size) && m_heap_region_start <= addr &&
addr + size - 1 <= m_heap_region_end - 1;
}
public: public:
static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout, static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout,

View File

@ -38,7 +38,7 @@ namespace {
*/ */
void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
KProcessAddress stack_top) { KProcessAddress stack_top) {
const KProcessAddress entry_point = owner_process.GetPageTable().GetCodeRegionStart(); const KProcessAddress entry_point = owner_process.PageTable().GetCodeRegionStart();
ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1)); ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
KThread* thread = KThread::Create(system.Kernel()); KThread* thread = KThread::Create(system.Kernel());

View File

@ -109,6 +109,16 @@ public:
static Result Initialize(KProcess* process, Core::System& system, std::string process_name, static Result Initialize(KProcess* process, Core::System& system, std::string process_name,
ProcessType type, KResourceLimit* res_limit); ProcessType type, KResourceLimit* res_limit);
/// Gets a reference to the process' page table.
KPageTable& PageTable() {
return m_page_table;
}
/// Gets const a reference to the process' page table.
const KPageTable& PageTable() const {
return m_page_table;
}
/// Gets a reference to the process' page table. /// Gets a reference to the process' page table.
KPageTable& GetPageTable() { KPageTable& GetPageTable() {
return m_page_table; return m_page_table;

View File

@ -90,8 +90,8 @@ Result KSharedMemory::Map(KProcess& target_process, KProcessAddress address, std
R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission); R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission);
} }
R_RETURN(target_process.GetPageTable().MapPageGroup( R_RETURN(target_process.PageTable().MapPageGroup(address, *m_page_group, KMemoryState::Shared,
address, *m_page_group, KMemoryState::Shared, ConvertToKMemoryPermission(map_perm))); ConvertToKMemoryPermission(map_perm)));
} }
Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address, Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address,
@ -100,7 +100,7 @@ Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address,
R_UNLESS(m_size == unmap_size, ResultInvalidSize); R_UNLESS(m_size == unmap_size, ResultInvalidSize);
R_RETURN( R_RETURN(
target_process.GetPageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::Shared)); target_process.PageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::Shared));
} }
} // namespace Kernel } // namespace Kernel

View File

@ -302,12 +302,12 @@ Result KThread::InitializeServiceThread(Core::System& system, KThread* thread,
std::function<void()>&& func, s32 prio, s32 virt_core, std::function<void()>&& func, s32 prio, s32 virt_core,
KProcess* owner) { KProcess* owner) {
system.Kernel().GlobalSchedulerContext().AddThread(thread); system.Kernel().GlobalSchedulerContext().AddThread(thread);
std::function<void()> func2{[&system, func_{std::move(func)}] { std::function<void()> func2{[&system, func{std::move(func)}] {
// Similar to UserModeThreadStarter. // Similar to UserModeThreadStarter.
system.Kernel().CurrentScheduler()->OnThreadStart(); system.Kernel().CurrentScheduler()->OnThreadStart();
// Run the guest function. // Run the guest function.
func_(); func();
// Exit. // Exit.
Svc::ExitThread(system); Svc::ExitThread(system);

View File

@ -25,9 +25,9 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
// Map the address in. // Map the address in.
const auto phys_addr = kernel.System().DeviceMemory().GetPhysicalAddr(page_buf); const auto phys_addr = kernel.System().DeviceMemory().GetPhysicalAddr(page_buf);
R_TRY(m_owner->GetPageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, phys_addr, R_TRY(m_owner->PageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, phys_addr,
KMemoryState::ThreadLocal, KMemoryState::ThreadLocal,
KMemoryPermission::UserReadWrite)); KMemoryPermission::UserReadWrite));
// We succeeded. // We succeeded.
page_buf_guard.Cancel(); page_buf_guard.Cancel();
@ -37,11 +37,11 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
Result KThreadLocalPage::Finalize() { Result KThreadLocalPage::Finalize() {
// Get the physical address of the page. // Get the physical address of the page.
const KPhysicalAddress phys_addr = m_owner->GetPageTable().GetPhysicalAddr(m_virt_addr); const KPhysicalAddress phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr);
ASSERT(phys_addr); ASSERT(phys_addr);
// Unmap the page. // Unmap the page.
R_TRY(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState::ThreadLocal)); R_TRY(m_owner->PageTable().UnmapPages(this->GetAddress(), 1, KMemoryState::ThreadLocal));
// Free the page. // Free the page.
KPageBuffer::Free(*m_kernel, KPageBuffer::FromPhysicalAddress(m_kernel->System(), phys_addr)); KPageBuffer::Free(*m_kernel, KPageBuffer::FromPhysicalAddress(m_kernel->System(), phys_addr));

View File

@ -1089,15 +1089,15 @@ static std::jthread RunHostThreadFunc(KernelCore& kernel, KProcess* process,
KThread::Register(kernel, thread); KThread::Register(kernel, thread);
return std::jthread( return std::jthread(
[&kernel, thread, thread_name_{std::move(thread_name)}, func_{std::move(func)}] { [&kernel, thread, thread_name{std::move(thread_name)}, func{std::move(func)}] {
// Set the thread name. // Set the thread name.
Common::SetCurrentThreadName(thread_name_.c_str()); Common::SetCurrentThreadName(thread_name.c_str());
// Set the thread as current. // Set the thread as current.
kernel.RegisterHostThread(thread); kernel.RegisterHostThread(thread);
// Run the callback. // Run the callback.
func_(); func();
// Close the thread. // Close the thread.
// This will free the process if it is the last reference. // This will free the process if it is the last reference.

View File

@ -17,9 +17,7 @@ PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system, KSchedu
// a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager.
auto& kernel = system.Kernel(); auto& kernel = system.Kernel();
m_arm_interface = std::make_unique<Core::ARM_Dynarmic_64>( m_arm_interface = std::make_unique<Core::ARM_Dynarmic_64>(
system, kernel.IsMulticore(), system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), m_core_index);
reinterpret_cast<Core::DynarmicExclusiveMonitor&>(kernel.GetExclusiveMonitor()),
m_core_index);
#else #else
#error Platform not supported yet. #error Platform not supported yet.
#endif #endif
@ -33,9 +31,7 @@ void PhysicalCore::Initialize(bool is_64_bit) {
if (!is_64_bit) { if (!is_64_bit) {
// We already initialized a 64-bit core, replace with a 32-bit one. // We already initialized a 64-bit core, replace with a 32-bit one.
m_arm_interface = std::make_unique<Core::ARM_Dynarmic_32>( m_arm_interface = std::make_unique<Core::ARM_Dynarmic_32>(
m_system, kernel.IsMulticore(), m_system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), m_core_index);
reinterpret_cast<Core::DynarmicExclusiveMonitor&>(kernel.GetExclusiveMonitor()),
m_core_index);
} }
#else #else
#error Platform not supported yet. #error Platform not supported yet.

View File

@ -42,7 +42,7 @@ Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 ad
R_UNLESS(process.IsNotNull(), ResultInvalidHandle); R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Verify the region is within range. // Verify the region is within range.
auto& page_table = process->GetPageTable(); auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Perform the operation. // Perform the operation.

View File

@ -48,7 +48,7 @@ Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t
SCOPE_EXIT({ code_mem->Close(); }); SCOPE_EXIT({ code_mem->Close(); });
// Verify that the region is in range. // Verify that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size), R_UNLESS(GetCurrentProcess(system.Kernel()).PageTable().Contains(address, size),
ResultInvalidCurrentMemory); ResultInvalidCurrentMemory);
// Initialize the code memory. // Initialize the code memory.
@ -92,7 +92,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
case CodeMemoryOperation::Map: { case CodeMemoryOperation::Map: {
// Check that the region is in range. // Check that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel()) R_UNLESS(GetCurrentProcess(system.Kernel())
.GetPageTable() .PageTable()
.CanContain(address, size, KMemoryState::CodeOut), .CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion); ResultInvalidMemoryRegion);
@ -105,7 +105,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
case CodeMemoryOperation::Unmap: { case CodeMemoryOperation::Unmap: {
// Check that the region is in range. // Check that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel()) R_UNLESS(GetCurrentProcess(system.Kernel())
.GetPageTable() .PageTable()
.CanContain(address, size, KMemoryState::CodeOut), .CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion); ResultInvalidMemoryRegion);
@ -117,8 +117,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
} break; } break;
case CodeMemoryOperation::MapToOwner: { case CodeMemoryOperation::MapToOwner: {
// Check that the region is in range. // Check that the region is in range.
R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size, R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size,
KMemoryState::GeneratedCode), KMemoryState::GeneratedCode),
ResultInvalidMemoryRegion); ResultInvalidMemoryRegion);
// Check the memory permission. // Check the memory permission.
@ -129,8 +129,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
} break; } break;
case CodeMemoryOperation::UnmapFromOwner: { case CodeMemoryOperation::UnmapFromOwner: {
// Check that the region is in range. // Check that the region is in range.
R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size, R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size,
KMemoryState::GeneratedCode), KMemoryState::GeneratedCode),
ResultInvalidMemoryRegion); ResultInvalidMemoryRegion);
// Check the memory permission. // Check the memory permission.

View File

@ -107,7 +107,7 @@ Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Han
R_UNLESS(process.IsNotNull(), ResultInvalidHandle); R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range. // Validate that the process address is within range.
auto& page_table = process->GetPageTable(); auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
// Map. // Map.
@ -148,7 +148,7 @@ Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Han
R_UNLESS(process.IsNotNull(), ResultInvalidHandle); R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range. // Validate that the process address is within range.
auto& page_table = process->GetPageTable(); auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
// Map. // Map.
@ -180,7 +180,7 @@ Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle p
R_UNLESS(process.IsNotNull(), ResultInvalidHandle); R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range. // Validate that the process address is within range.
auto& page_table = process->GetPageTable(); auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
R_RETURN(das->Unmap(std::addressof(page_table), process_address, size, device_address)); R_RETURN(das->Unmap(std::addressof(page_table), process_address, size, device_address));

View File

@ -54,35 +54,35 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
R_SUCCEED(); R_SUCCEED();
case InfoType::AliasRegionAddress: case InfoType::AliasRegionAddress:
*result = GetInteger(process->GetPageTable().GetAliasRegionStart()); *result = GetInteger(process->PageTable().GetAliasRegionStart());
R_SUCCEED(); R_SUCCEED();
case InfoType::AliasRegionSize: case InfoType::AliasRegionSize:
*result = process->GetPageTable().GetAliasRegionSize(); *result = process->PageTable().GetAliasRegionSize();
R_SUCCEED(); R_SUCCEED();
case InfoType::HeapRegionAddress: case InfoType::HeapRegionAddress:
*result = GetInteger(process->GetPageTable().GetHeapRegionStart()); *result = GetInteger(process->PageTable().GetHeapRegionStart());
R_SUCCEED(); R_SUCCEED();
case InfoType::HeapRegionSize: case InfoType::HeapRegionSize:
*result = process->GetPageTable().GetHeapRegionSize(); *result = process->PageTable().GetHeapRegionSize();
R_SUCCEED(); R_SUCCEED();
case InfoType::AslrRegionAddress: case InfoType::AslrRegionAddress:
*result = GetInteger(process->GetPageTable().GetAliasCodeRegionStart()); *result = GetInteger(process->PageTable().GetAliasCodeRegionStart());
R_SUCCEED(); R_SUCCEED();
case InfoType::AslrRegionSize: case InfoType::AslrRegionSize:
*result = process->GetPageTable().GetAliasCodeRegionSize(); *result = process->PageTable().GetAliasCodeRegionSize();
R_SUCCEED(); R_SUCCEED();
case InfoType::StackRegionAddress: case InfoType::StackRegionAddress:
*result = GetInteger(process->GetPageTable().GetStackRegionStart()); *result = GetInteger(process->PageTable().GetStackRegionStart());
R_SUCCEED(); R_SUCCEED();
case InfoType::StackRegionSize: case InfoType::StackRegionSize:
*result = process->GetPageTable().GetStackRegionSize(); *result = process->PageTable().GetStackRegionSize();
R_SUCCEED(); R_SUCCEED();
case InfoType::TotalMemorySize: case InfoType::TotalMemorySize:

View File

@ -63,13 +63,36 @@ Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 s
R_THROW(ResultInvalidCurrentMemory); R_THROW(ResultInvalidCurrentMemory);
} }
if (!manager.Contains(src_addr, size)) { if (!manager.IsInsideAddressSpace(src_addr, size)) {
LOG_ERROR(Kernel_SVC, LOG_ERROR(Kernel_SVC,
"Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}",
src_addr, size); src_addr, size);
R_THROW(ResultInvalidCurrentMemory); R_THROW(ResultInvalidCurrentMemory);
} }
if (manager.IsOutsideStackRegion(dst_addr, size)) {
LOG_ERROR(Kernel_SVC,
"Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}",
dst_addr, size);
R_THROW(ResultInvalidMemoryRegion);
}
if (manager.IsInsideHeapRegion(dst_addr, size)) {
LOG_ERROR(Kernel_SVC,
"Destination does not fit within the heap region, addr=0x{:016X}, "
"size=0x{:016X}",
dst_addr, size);
R_THROW(ResultInvalidMemoryRegion);
}
if (manager.IsInsideAliasRegion(dst_addr, size)) {
LOG_ERROR(Kernel_SVC,
"Destination does not fit within the map region, addr=0x{:016X}, "
"size=0x{:016X}",
dst_addr, size);
R_THROW(ResultInvalidMemoryRegion);
}
R_SUCCEED(); R_SUCCEED();
} }
@ -89,7 +112,7 @@ Result SetMemoryPermission(Core::System& system, u64 address, u64 size, MemoryPe
R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission); R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission);
// Validate that the region is in range for the current process. // Validate that the region is in range for the current process.
auto& page_table = GetCurrentProcess(system.Kernel()).GetPageTable(); auto& page_table = GetCurrentProcess(system.Kernel()).PageTable();
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Set the memory attribute. // Set the memory attribute.
@ -113,7 +136,7 @@ Result SetMemoryAttribute(Core::System& system, u64 address, u64 size, u32 mask,
R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination); R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination);
// Validate that the region is in range for the current process. // Validate that the region is in range for the current process.
auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()}; auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Set the memory attribute. // Set the memory attribute.
@ -125,7 +148,7 @@ Result MapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size); src_addr, size);
auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()}; auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)};
result.IsError()) { result.IsError()) {
@ -140,7 +163,7 @@ Result UnmapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size); src_addr, size);
auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()}; auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)};
result.IsError()) { result.IsError()) {

View File

@ -16,7 +16,7 @@ Result SetHeapSize(Core::System& system, u64* out_address, u64 size) {
R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize); R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize);
// Set the heap size. // Set the heap size.
R_RETURN(GetCurrentProcess(system.Kernel()).GetPageTable().SetHeapSize(out_address, size)); R_RETURN(GetCurrentProcess(system.Kernel()).PageTable().SetHeapSize(out_address, size));
} }
/// Maps memory at a desired address /// Maps memory at a desired address
@ -44,21 +44,21 @@ Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
} }
KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())}; KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
auto& page_table{current_process->GetPageTable()}; auto& page_table{current_process->PageTable()};
if (current_process->GetSystemResourceSize() == 0) { if (current_process->GetSystemResourceSize() == 0) {
LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
R_THROW(ResultInvalidState); R_THROW(ResultInvalidState);
} }
if (!page_table.Contains(addr, size)) { if (!page_table.IsInsideAddressSpace(addr, size)) {
LOG_ERROR(Kernel_SVC, LOG_ERROR(Kernel_SVC,
"Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr,
size); size);
R_THROW(ResultInvalidMemoryRegion); R_THROW(ResultInvalidMemoryRegion);
} }
if (!page_table.IsInAliasRegion(addr, size)) { if (page_table.IsOutsideAliasRegion(addr, size)) {
LOG_ERROR(Kernel_SVC, LOG_ERROR(Kernel_SVC,
"Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr,
size); size);
@ -93,21 +93,21 @@ Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
} }
KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())}; KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
auto& page_table{current_process->GetPageTable()}; auto& page_table{current_process->PageTable()};
if (current_process->GetSystemResourceSize() == 0) { if (current_process->GetSystemResourceSize() == 0) {
LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
R_THROW(ResultInvalidState); R_THROW(ResultInvalidState);
} }
if (!page_table.Contains(addr, size)) { if (!page_table.IsInsideAddressSpace(addr, size)) {
LOG_ERROR(Kernel_SVC, LOG_ERROR(Kernel_SVC,
"Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr,
size); size);
R_THROW(ResultInvalidMemoryRegion); R_THROW(ResultInvalidMemoryRegion);
} }
if (!page_table.IsInAliasRegion(addr, size)) { if (page_table.IsOutsideAliasRegion(addr, size)) {
LOG_ERROR(Kernel_SVC, LOG_ERROR(Kernel_SVC,
"Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr,
size); size);

View File

@ -66,8 +66,8 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_proc
auto& kernel = system.Kernel(); auto& kernel = system.Kernel();
const auto total_copy_size = out_process_ids_size * sizeof(u64); const auto total_copy_size = out_process_ids_size * sizeof(u64);
if (out_process_ids_size > 0 && if (out_process_ids_size > 0 && !GetCurrentProcess(kernel).PageTable().IsInsideAddressSpace(
!GetCurrentProcess(kernel).GetPageTable().Contains(out_process_ids, total_copy_size)) { out_process_ids, total_copy_size)) {
LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
out_process_ids, out_process_ids + total_copy_size); out_process_ids, out_process_ids + total_copy_size);
R_THROW(ResultInvalidCurrentMemory); R_THROW(ResultInvalidCurrentMemory);

View File

@ -49,7 +49,7 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, u
R_UNLESS(process.IsNotNull(), ResultInvalidHandle); R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the address is in range. // Validate that the address is in range.
auto& page_table = process->GetPageTable(); auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Set the memory permission. // Set the memory permission.
@ -77,8 +77,8 @@ Result MapProcessMemory(Core::System& system, u64 dst_address, Handle process_ha
R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
// Get the page tables. // Get the page tables.
auto& dst_pt = dst_process->GetPageTable(); auto& dst_pt = dst_process->PageTable();
auto& src_pt = src_process->GetPageTable(); auto& src_pt = src_process->PageTable();
// Validate that the mapping is in range. // Validate that the mapping is in range.
R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory); R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory);
@ -118,8 +118,8 @@ Result UnmapProcessMemory(Core::System& system, u64 dst_address, Handle process_
R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
// Get the page tables. // Get the page tables.
auto& dst_pt = dst_process->GetPageTable(); auto& dst_pt = dst_process->PageTable();
auto& src_pt = src_process->GetPageTable(); auto& src_pt = src_process->PageTable();
// Validate that the mapping is in range. // Validate that the mapping is in range.
R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory); R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory);
@ -178,8 +178,8 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
R_THROW(ResultInvalidHandle); R_THROW(ResultInvalidHandle);
} }
auto& page_table = process->GetPageTable(); auto& page_table = process->PageTable();
if (!page_table.Contains(src_address, size)) { if (!page_table.IsInsideAddressSpace(src_address, size)) {
LOG_ERROR(Kernel_SVC, LOG_ERROR(Kernel_SVC,
"Source address range is not within the address space (src_address=0x{:016X}, " "Source address range is not within the address space (src_address=0x{:016X}, "
"size=0x{:016X}).", "size=0x{:016X}).",
@ -187,6 +187,14 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
R_THROW(ResultInvalidCurrentMemory); R_THROW(ResultInvalidCurrentMemory);
} }
if (!page_table.IsInsideASLRRegion(dst_address, size)) {
LOG_ERROR(Kernel_SVC,
"Destination address range is not within the ASLR region (dst_address=0x{:016X}, "
"size=0x{:016X}).",
dst_address, size);
R_THROW(ResultInvalidMemoryRegion);
}
R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size)); R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size));
} }
@ -238,8 +246,8 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
R_THROW(ResultInvalidHandle); R_THROW(ResultInvalidHandle);
} }
auto& page_table = process->GetPageTable(); auto& page_table = process->PageTable();
if (!page_table.Contains(src_address, size)) { if (!page_table.IsInsideAddressSpace(src_address, size)) {
LOG_ERROR(Kernel_SVC, LOG_ERROR(Kernel_SVC,
"Source address range is not within the address space (src_address=0x{:016X}, " "Source address range is not within the address space (src_address=0x{:016X}, "
"size=0x{:016X}).", "size=0x{:016X}).",
@ -247,6 +255,14 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
R_THROW(ResultInvalidCurrentMemory); R_THROW(ResultInvalidCurrentMemory);
} }
if (!page_table.IsInsideASLRRegion(dst_address, size)) {
LOG_ERROR(Kernel_SVC,
"Destination address range is not within the ASLR region (dst_address=0x{:016X}, "
"size=0x{:016X}).",
dst_address, size);
R_THROW(ResultInvalidMemoryRegion);
}
R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size, R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size,
KPageTable::ICacheInvalidationStrategy::InvalidateAll)); KPageTable::ICacheInvalidationStrategy::InvalidateAll));
} }

View File

@ -31,7 +31,7 @@ Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageIn
} }
auto& current_memory{GetCurrentMemory(system.Kernel())}; auto& current_memory{GetCurrentMemory(system.Kernel())};
const auto memory_info{process->GetPageTable().QueryInfo(address).GetSvcMemoryInfo()}; const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()};
current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info)); current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info));

View File

@ -43,7 +43,7 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u
// Get the current process. // Get the current process.
auto& process = GetCurrentProcess(system.Kernel()); auto& process = GetCurrentProcess(system.Kernel());
auto& page_table = process.GetPageTable(); auto& page_table = process.PageTable();
// Get the shared memory. // Get the shared memory.
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle); KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
@ -73,7 +73,7 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address,
// Get the current process. // Get the current process.
auto& process = GetCurrentProcess(system.Kernel()); auto& process = GetCurrentProcess(system.Kernel());
auto& page_table = process.GetPageTable(); auto& page_table = process.PageTable();
// Get the shared memory. // Get the shared memory.
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle); KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);

View File

@ -236,7 +236,7 @@ Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_
const auto total_copy_size = out_thread_ids_size * sizeof(u64); const auto total_copy_size = out_thread_ids_size * sizeof(u64);
if (out_thread_ids_size > 0 && if (out_thread_ids_size > 0 &&
!current_process->GetPageTable().Contains(out_thread_ids, total_copy_size)) { !current_process->PageTable().IsInsideAddressSpace(out_thread_ids, total_copy_size)) {
LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
out_thread_ids, out_thread_ids + total_copy_size); out_thread_ids, out_thread_ids + total_copy_size);
R_THROW(ResultInvalidCurrentMemory); R_THROW(ResultInvalidCurrentMemory);

View File

@ -55,7 +55,7 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64
SCOPE_EXIT({ trmem->Close(); }); SCOPE_EXIT({ trmem->Close(); });
// Ensure that the region is in range. // Ensure that the region is in range.
R_UNLESS(process.GetPageTable().Contains(address, size), ResultInvalidCurrentMemory); R_UNLESS(process.PageTable().Contains(address, size), ResultInvalidCurrentMemory);
// Initialize the transfer memory. // Initialize the transfer memory.
R_TRY(trmem->Initialize(address, size, map_perm)); R_TRY(trmem->Initialize(address, size, map_perm));

View File

@ -506,8 +506,8 @@ void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) {
void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
idle_time_detection_extension = rp.Pop<u32>(); idle_time_detection_extension = rp.Pop<u32>();
LOG_DEBUG(Service_AM, "(STUBBED) called idle_time_detection_extension={}", LOG_WARNING(Service_AM, "(STUBBED) called idle_time_detection_extension={}",
idle_time_detection_extension); idle_time_detection_extension);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);

View File

@ -318,15 +318,15 @@ public:
return false; return false;
} }
if (!page_table.Contains(out_addr, size)) { if (!page_table.IsInsideAddressSpace(out_addr, size)) {
return false; return false;
} }
if (page_table.IsInHeapRegion(out_addr, size)) { if (page_table.IsInsideHeapRegion(out_addr, size)) {
return false; return false;
} }
if (page_table.IsInAliasRegion(out_addr, size)) { if (page_table.IsInsideAliasRegion(out_addr, size)) {
return false; return false;
} }
@ -358,7 +358,7 @@ public:
} }
ResultVal<VAddr> MapProcessCodeMemory(Kernel::KProcess* process, VAddr base_addr, u64 size) { ResultVal<VAddr> MapProcessCodeMemory(Kernel::KProcess* process, VAddr base_addr, u64 size) {
auto& page_table{process->GetPageTable()}; auto& page_table{process->PageTable()};
VAddr addr{}; VAddr addr{};
for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) {
@ -382,7 +382,7 @@ public:
ResultVal<VAddr> MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size, ResultVal<VAddr> MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size,
VAddr bss_addr, std::size_t bss_size, std::size_t size) { VAddr bss_addr, std::size_t bss_size, std::size_t size) {
for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) {
auto& page_table{process->GetPageTable()}; auto& page_table{process->PageTable()};
VAddr addr{}; VAddr addr{};
CASCADE_RESULT(addr, MapProcessCodeMemory(process, nro_addr, nro_size)); CASCADE_RESULT(addr, MapProcessCodeMemory(process, nro_addr, nro_size));
@ -437,12 +437,12 @@ public:
CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start, CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start,
nro_header.segment_headers[DATA_INDEX].memory_size); nro_header.segment_headers[DATA_INDEX].memory_size);
CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission( CASCADE_CODE(process->PageTable().SetProcessMemoryPermission(
text_start, ro_start - text_start, Kernel::Svc::MemoryPermission::ReadExecute)); text_start, ro_start - text_start, Kernel::Svc::MemoryPermission::ReadExecute));
CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission( CASCADE_CODE(process->PageTable().SetProcessMemoryPermission(
ro_start, data_start - ro_start, Kernel::Svc::MemoryPermission::Read)); ro_start, data_start - ro_start, Kernel::Svc::MemoryPermission::Read));
return process->GetPageTable().SetProcessMemoryPermission( return process->PageTable().SetProcessMemoryPermission(
data_start, bss_end_addr - data_start, Kernel::Svc::MemoryPermission::ReadWrite); data_start, bss_end_addr - data_start, Kernel::Svc::MemoryPermission::ReadWrite);
} }
@ -571,7 +571,7 @@ public:
Result UnmapNro(const NROInfo& info) { Result UnmapNro(const NROInfo& info) {
// Each region must be unmapped separately to validate memory state // Each region must be unmapped separately to validate memory state
auto& page_table{system.ApplicationProcess()->GetPageTable()}; auto& page_table{system.ApplicationProcess()->PageTable()};
if (info.bss_size != 0) { if (info.bss_size != 0) {
CASCADE_CODE(page_table.UnmapCodeMemory( CASCADE_CODE(page_table.UnmapCodeMemory(
@ -643,7 +643,7 @@ public:
initialized = true; initialized = true;
current_map_addr = current_map_addr =
GetInteger(system.ApplicationProcess()->GetPageTable().GetAliasCodeRegionStart()); GetInteger(system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart());
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);

View File

@ -180,7 +180,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
} }
void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
std::span<const u8> seed) { const std::vector<u8>& seed) {
// Initialize context // Initialize context
ctx.used = false; ctx.used = false;
ctx.counter = 0; ctx.counter = 0;

View File

@ -75,7 +75,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
// Initializes mbedtls context // Initializes mbedtls context
void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
std::span<const u8> seed); const std::vector<u8>& seed);
// Feeds data to mbedtls context to generate the derived key // Feeds data to mbedtls context to generate the derived key
void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output); void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output);

View File

@ -34,6 +34,8 @@
#include "core/hle/service/nfc/mifare_result.h" #include "core/hle/service/nfc/mifare_result.h"
#include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/nfc/nfc_result.h"
#include "core/hle/service/time/time_manager.h" #include "core/hle/service/time/time_manager.h"
#include "core/hle/service/time/time_zone_content_manager.h"
#include "core/hle/service/time/time_zone_types.h"
namespace Service::NFC { namespace Service::NFC {
NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_,
@ -1484,7 +1486,6 @@ DeviceState NfcDevice::GetCurrentState() const {
} }
Result NfcDevice::GetNpadId(Core::HID::NpadIdType& out_npad_id) const { Result NfcDevice::GetNpadId(Core::HID::NpadIdType& out_npad_id) const {
// TODO: This should get the npad id from nn::hid::system::GetXcdHandleForNpadWithNfc
out_npad_id = npad_id; out_npad_id = npad_id;
return ResultSuccess; return ResultSuccess;
} }

View File

@ -1,8 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <algorithm>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/hid/hid_types.h" #include "core/hid/hid_types.h"
@ -12,7 +10,6 @@
#include "core/hle/service/nfc/common/device_manager.h" #include "core/hle/service/nfc/common/device_manager.h"
#include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/nfc/nfc_result.h"
#include "core/hle/service/time/clock_types.h" #include "core/hle/service/time/clock_types.h"
#include "core/hle/service/time/time_manager.h"
namespace Service::NFC { namespace Service::NFC {
@ -54,53 +51,22 @@ Result DeviceManager::Finalize() {
return ResultSuccess; return ResultSuccess;
} }
Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices, Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices,
bool skip_fatal_errors) const { std::size_t max_allowed_devices) const {
std::scoped_lock lock{mutex};
if (max_allowed_devices < 1) {
return ResultInvalidArgument;
}
Result result = IsNfcParameterSet();
if (result.IsError()) {
return result;
}
result = IsNfcEnabled();
if (result.IsError()) {
return result;
}
result = IsNfcInitialized();
if (result.IsError()) {
return result;
}
for (auto& device : devices) { for (auto& device : devices) {
if (nfp_devices.size() >= max_allowed_devices) { if (nfp_devices.size() >= max_allowed_devices) {
continue; continue;
} }
if (skip_fatal_errors) { if (device->GetCurrentState() != DeviceState::Unavailable) {
constexpr u64 MinimumRecoveryTime = 60; nfp_devices.push_back(device->GetHandle());
auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()};
const u64 elapsed_time = standard_steady_clock.GetCurrentTimePoint(system).time_point -
time_since_last_error;
if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) {
continue;
}
} }
if (device->GetCurrentState() == DeviceState::Unavailable) {
continue;
}
nfp_devices.push_back(device->GetHandle());
} }
if (nfp_devices.empty()) { if (nfp_devices.empty()) {
return ResultDeviceNotFound; return ResultDeviceNotFound;
} }
return result; return ResultSuccess;
} }
DeviceState DeviceManager::GetDeviceState(u64 device_handle) const { DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
@ -113,10 +79,10 @@ DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
return device->GetCurrentState(); return device->GetCurrentState();
} }
return DeviceState::Finalized; return DeviceState::Unavailable;
} }
Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) { Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -162,7 +128,7 @@ Result DeviceManager::StopDetection(u64 device_handle) {
return result; return result;
} }
Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) { Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -176,46 +142,24 @@ Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) {
return result; return result;
} }
Result DeviceManager::AttachActivateEvent(Kernel::KReadableEvent** out_event, Kernel::KReadableEvent& DeviceManager::AttachActivateEvent(u64 device_handle) const {
u64 device_handle) const { std::scoped_lock lock{mutex};
std::vector<u64> nfp_devices;
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
Result result = ListDevices(nfp_devices, 9, false); GetDeviceFromHandle(device_handle, device, false);
if (result.IsSuccess()) { // TODO: Return proper error code on failure
result = CheckHandleOnList(device_handle, nfp_devices); return device->GetActivateEvent();
}
if (result.IsSuccess()) {
result = GetDeviceFromHandle(device_handle, device, false);
}
if (result.IsSuccess()) {
*out_event = &device->GetActivateEvent();
}
return result;
} }
Result DeviceManager::AttachDeactivateEvent(Kernel::KReadableEvent** out_event, Kernel::KReadableEvent& DeviceManager::AttachDeactivateEvent(u64 device_handle) const {
u64 device_handle) const { std::scoped_lock lock{mutex};
std::vector<u64> nfp_devices;
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
Result result = ListDevices(nfp_devices, 9, false); GetDeviceFromHandle(device_handle, device, false);
if (result.IsSuccess()) { // TODO: Return proper error code on failure
result = CheckHandleOnList(device_handle, nfp_devices); return device->GetDeactivateEvent();
}
if (result.IsSuccess()) {
result = GetDeviceFromHandle(device_handle, device, false);
}
if (result.IsSuccess()) {
*out_event = &device->GetDeactivateEvent();
}
return result;
} }
Result DeviceManager::ReadMifare(u64 device_handle, Result DeviceManager::ReadMifare(u64 device_handle,
@ -309,7 +253,7 @@ Result DeviceManager::OpenApplicationArea(u64 device_handle, u32 access_id) {
return result; return result;
} }
Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) { Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -380,7 +324,7 @@ Result DeviceManager::CreateApplicationArea(u64 device_handle, u32 access_id,
return result; return result;
} }
Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) { Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -394,7 +338,7 @@ Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& regi
return result; return result;
} }
Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) { Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -408,7 +352,7 @@ Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_i
return result; return result;
} }
Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) { Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -455,7 +399,7 @@ Result DeviceManager::Format(u64 device_handle) {
return result; return result;
} }
Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) { Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -470,7 +414,7 @@ Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info
} }
Result DeviceManager::GetRegisterInfoPrivate(u64 device_handle, Result DeviceManager::GetRegisterInfoPrivate(u64 device_handle,
NFP::RegisterInfoPrivate& register_info) { NFP::RegisterInfoPrivate& register_info) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -527,7 +471,7 @@ Result DeviceManager::DeleteApplicationArea(u64 device_handle) {
return result; return result;
} }
Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) { Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -541,7 +485,7 @@ Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_applica
return result; return result;
} }
Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) { Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -597,7 +541,7 @@ Result DeviceManager::BreakTag(u64 device_handle, NFP::BreakType break_type) {
return result; return result;
} }
Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) { Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -649,19 +593,6 @@ Result DeviceManager::WriteNtf(u64 device_handle, NFP::WriteType, std::span<cons
return result; return result;
} }
Result DeviceManager::CheckHandleOnList(u64 device_handle,
const std::span<const u64> device_list) const {
if (device_list.size() < 1) {
return ResultDeviceNotFound;
}
if (std::find(device_list.begin(), device_list.end(), device_handle) != device_list.end()) {
return ResultSuccess;
}
return ResultDeviceNotFound;
}
Result DeviceManager::GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& nfc_device, Result DeviceManager::GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& nfc_device,
bool check_state) const { bool check_state) const {
if (check_state) { if (check_state) {
@ -716,7 +647,7 @@ Result DeviceManager::GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& de
} }
Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
Result operation_result) { Result operation_result) const {
if (operation_result.IsSuccess()) { if (operation_result.IsSuccess()) {
return operation_result; return operation_result;
} }
@ -738,12 +669,6 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
return device_state; return device_state;
} }
if (operation_result == ResultUnknown112 || operation_result == ResultUnknown114 ||
operation_result == ResultUnknown115) {
auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()};
time_since_last_error = standard_steady_clock.GetCurrentTimePoint(system).time_point;
}
return operation_result; return operation_result;
} }

View File

@ -27,16 +27,15 @@ public:
// Nfc device manager // Nfc device manager
Result Initialize(); Result Initialize();
Result Finalize(); Result Finalize();
Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices, Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices) const;
bool skip_fatal_errors) const;
DeviceState GetDeviceState(u64 device_handle) const; DeviceState GetDeviceState(u64 device_handle) const;
Result GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id); Result GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const;
Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const; Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const;
Result StartDetection(u64 device_handle, NfcProtocol tag_protocol); Result StartDetection(u64 device_handle, NfcProtocol tag_protocol);
Result StopDetection(u64 device_handle); Result StopDetection(u64 device_handle);
Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info); Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info) const;
Result AttachActivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const; Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const;
Result AttachDeactivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const; Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const;
Result ReadMifare(u64 device_handle, Result ReadMifare(u64 device_handle,
const std::span<const MifareReadBlockParameter> read_parameters, const std::span<const MifareReadBlockParameter> read_parameters,
std::span<MifareReadBlockData> read_data); std::span<MifareReadBlockData> read_data);
@ -49,28 +48,28 @@ public:
Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target); Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target);
Result Unmount(u64 device_handle); Result Unmount(u64 device_handle);
Result OpenApplicationArea(u64 device_handle, u32 access_id); Result OpenApplicationArea(u64 device_handle, u32 access_id);
Result GetApplicationArea(u64 device_handle, std::span<u8> data); Result GetApplicationArea(u64 device_handle, std::span<u8> data) const;
Result SetApplicationArea(u64 device_handle, std::span<const u8> data); Result SetApplicationArea(u64 device_handle, std::span<const u8> data);
Result Flush(u64 device_handle); Result Flush(u64 device_handle);
Result Restore(u64 device_handle); Result Restore(u64 device_handle);
Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data); Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info); Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const;
Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info); Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const;
Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info); Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const;
u32 GetApplicationAreaSize() const; u32 GetApplicationAreaSize() const;
Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data); Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
Result Format(u64 device_handle); Result Format(u64 device_handle);
Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info); Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const;
Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info); Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info) const;
Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info); Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info);
Result DeleteRegisterInfo(u64 device_handle); Result DeleteRegisterInfo(u64 device_handle);
Result DeleteApplicationArea(u64 device_handle); Result DeleteApplicationArea(u64 device_handle);
Result ExistsApplicationArea(u64 device_handle, bool& has_application_area); Result ExistsApplicationArea(u64 device_handle, bool& has_application_area) const;
Result GetAll(u64 device_handle, NFP::NfpData& nfp_data); Result GetAll(u64 device_handle, NFP::NfpData& nfp_data) const;
Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data); Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data);
Result FlushDebug(u64 device_handle); Result FlushDebug(u64 device_handle);
Result BreakTag(u64 device_handle, NFP::BreakType break_type); Result BreakTag(u64 device_handle, NFP::BreakType break_type);
Result ReadBackupData(u64 device_handle, std::span<u8> data); Result ReadBackupData(u64 device_handle, std::span<u8> data) const;
Result WriteBackupData(u64 device_handle, std::span<const u8> data); Result WriteBackupData(u64 device_handle, std::span<const u8> data);
Result WriteNtf(u64 device_handle, NFP::WriteType, std::span<const u8> data); Result WriteNtf(u64 device_handle, NFP::WriteType, std::span<const u8> data);
@ -79,20 +78,17 @@ private:
Result IsNfcParameterSet() const; Result IsNfcParameterSet() const;
Result IsNfcInitialized() const; Result IsNfcInitialized() const;
Result CheckHandleOnList(u64 device_handle, std::span<const u64> device_list) const;
Result GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& device, Result GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& device,
bool check_state) const; bool check_state) const;
Result GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& device) const; Result GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& device) const;
Result VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result operation_result); Result VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result operation_result) const;
Result CheckDeviceState(std::shared_ptr<NfcDevice> device) const; Result CheckDeviceState(std::shared_ptr<NfcDevice> device) const;
std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle); std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle);
const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const; const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const;
bool is_initialized = false; bool is_initialized = false;
u64 time_since_last_error = 0;
mutable std::mutex mutex; mutable std::mutex mutex;
std::array<std::shared_ptr<NfcDevice>, 10> devices{}; std::array<std::shared_ptr<NfcDevice>, 10> devices{};

View File

@ -79,7 +79,7 @@ void NfcInterface::ListDevices(HLERequestContext& ctx) {
const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>(); const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>();
LOG_DEBUG(Service_NFC, "called"); LOG_DEBUG(Service_NFC, "called");
auto result = GetManager()->ListDevices(nfp_devices, max_allowed_devices, true); auto result = GetManager()->ListDevices(nfp_devices, max_allowed_devices);
result = TranslateResultToServiceError(result); result = TranslateResultToServiceError(result);
if (result.IsError()) { if (result.IsError()) {
@ -190,13 +190,9 @@ void NfcInterface::AttachActivateEvent(HLERequestContext& ctx) {
const auto device_handle{rp.Pop<u64>()}; const auto device_handle{rp.Pop<u64>()};
LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
Kernel::KReadableEvent* out_event = nullptr;
auto result = GetManager()->AttachActivateEvent(&out_event, device_handle);
result = TranslateResultToServiceError(result);
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(result); rb.Push(ResultSuccess);
rb.PushCopyObjects(out_event); rb.PushCopyObjects(GetManager()->AttachActivateEvent(device_handle));
} }
void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) { void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
@ -204,13 +200,9 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
const auto device_handle{rp.Pop<u64>()}; const auto device_handle{rp.Pop<u64>()};
LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
Kernel::KReadableEvent* out_event = nullptr;
auto result = GetManager()->AttachDeactivateEvent(&out_event, device_handle);
result = TranslateResultToServiceError(result);
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(result); rb.Push(ResultSuccess);
rb.PushCopyObjects(out_event); rb.PushCopyObjects(GetManager()->AttachDeactivateEvent(device_handle));
} }
void NfcInterface::ReadMifare(HLERequestContext& ctx) { void NfcInterface::ReadMifare(HLERequestContext& ctx) {

View File

@ -17,10 +17,7 @@ constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77);
constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80); constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80);
constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88); constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88);
constexpr Result ResultTagRemoved(ErrorModule::NFC, 97); constexpr Result ResultTagRemoved(ErrorModule::NFC, 97);
constexpr Result ResultUnknown112(ErrorModule::NFC, 112);
constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113); constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113);
constexpr Result ResultUnknown114(ErrorModule::NFC, 114);
constexpr Result ResultUnknown115(ErrorModule::NFC, 115);
constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120); constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120);
constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128); constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128);
constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136); constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136);

View File

@ -7,7 +7,6 @@
#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/nifm/nifm.h" #include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/server_manager.h" #include "core/hle/service/server_manager.h"
#include "network/network.h"
namespace { namespace {

View File

@ -4,15 +4,14 @@
#pragma once #pragma once
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "network/network.h"
#include "network/room.h"
#include "network/room_member.h"
namespace Core { namespace Core {
class System; class System;
} }
namespace Network {
class RoomNetwork;
}
namespace Service::NIFM { namespace Service::NIFM {
void LoopProcess(Core::System& system); void LoopProcess(Core::System& system);

View File

@ -128,7 +128,7 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) {
} }
bool is_out_io{}; bool is_out_io{};
ASSERT(system.ApplicationProcess() ASSERT(system.ApplicationProcess()
->GetPageTable() ->PageTable()
.LockForMapDeviceAddressSpace(&is_out_io, handle_description->address, .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address,
handle_description->size, handle_description->size,
Kernel::KMemoryPermission::None, true, false) Kernel::KMemoryPermission::None, true, false)
@ -255,7 +255,7 @@ NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) {
if (auto freeInfo{file.FreeHandle(params.handle, false)}) { if (auto freeInfo{file.FreeHandle(params.handle, false)}) {
if (freeInfo->can_unlock) { if (freeInfo->can_unlock) {
ASSERT(system.ApplicationProcess() ASSERT(system.ApplicationProcess()
->GetPageTable() ->PageTable()
.UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size)
.IsSuccess()); .IsSuccess());
} }

View File

@ -10,15 +10,6 @@ namespace Service::Sockets {
constexpr Result ResultOverflow{ErrorModule::NSD, 6}; constexpr Result ResultOverflow{ErrorModule::NSD, 6};
// This is nn::oe::ServerEnvironmentType
enum class ServerEnvironmentType : u8 {
Dd,
Lp,
Sd,
Sp,
Dp,
};
NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} { NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
@ -45,7 +36,7 @@ NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
{62, nullptr, "DeleteSaveDataOfFsForTest"}, {62, nullptr, "DeleteSaveDataOfFsForTest"},
{63, nullptr, "IsChangeEnvironmentIdentifierDisabled"}, {63, nullptr, "IsChangeEnvironmentIdentifierDisabled"},
{64, nullptr, "SetWithoutDomainExchangeFqdns"}, {64, nullptr, "SetWithoutDomainExchangeFqdns"},
{100, &NSD::GetApplicationServerEnvironmentType, "GetApplicationServerEnvironmentType"}, {100, nullptr, "GetApplicationServerEnvironmentType"},
{101, nullptr, "SetApplicationServerEnvironmentType"}, {101, nullptr, "SetApplicationServerEnvironmentType"},
{102, nullptr, "DeleteApplicationServerEnvironmentType"}, {102, nullptr, "DeleteApplicationServerEnvironmentType"},
}; };
@ -103,12 +94,6 @@ void NSD::ResolveEx(HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void NSD::GetApplicationServerEnvironmentType(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(ServerEnvironmentType::Lp));
}
NSD::~NSD() = default; NSD::~NSD() = default;
} // namespace Service::Sockets } // namespace Service::Sockets

View File

@ -19,7 +19,6 @@ public:
private: private:
void Resolve(HLERequestContext& ctx); void Resolve(HLERequestContext& ctx);
void ResolveEx(HLERequestContext& ctx); void ResolveEx(HLERequestContext& ctx);
void GetApplicationServerEnvironmentType(HLERequestContext& ctx);
}; };
} // namespace Service::Sockets } // namespace Service::Sockets

View File

@ -3,15 +3,15 @@
#pragma once #pragma once
#include "core/hle/result.h"
#include "common/common_types.h"
#include <memory> #include <memory>
#include <span> #include <span>
#include <string> #include <string>
#include <vector> #include <vector>
#include "common/common_types.h"
#include "core/hle/result.h"
namespace Network { namespace Network {
class SocketBase; class SocketBase;
} }

View File

@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/hle/service/ssl/ssl_backend.h" #include "core/hle/service/ssl/ssl_backend.h"
#include "common/logging/log.h"
namespace Service::SSL { namespace Service::SSL {
ResultVal<std::unique_ptr<SSLConnectionBackend>> CreateSSLConnectionBackend() { ResultVal<std::unique_ptr<SSLConnectionBackend>> CreateSSLConnectionBackend() {

View File

@ -1,6 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
#include "common/fs/file.h"
#include "common/hex_util.h"
#include "common/string_util.h"
#include <mutex> #include <mutex>
#include <openssl/bio.h> #include <openssl/bio.h>
@ -8,14 +16,6 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include "common/fs/file.h"
#include "common/hex_util.h"
#include "common/string_util.h"
#include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
using namespace Common::FS; using namespace Common::FS;
namespace Service::SSL { namespace Service::SSL {

View File

@ -1,16 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <mutex> #include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
#include "common/error.h" #include "common/error.h"
#include "common/fs/file.h" #include "common/fs/file.h"
#include "common/hex_util.h" #include "common/hex_util.h"
#include "common/string_util.h" #include "common/string_util.h"
#include "core/hle/service/ssl/ssl_backend.h" #include <mutex>
#include "core/internal_network/network.h"
#include "core/internal_network/sockets.h"
namespace { namespace {
@ -20,7 +20,6 @@ namespace {
#define SECURITY_WIN32 #define SECURITY_WIN32
#include <schnlsp.h> #include <schnlsp.h>
#include <security.h> #include <security.h>
#include <wincrypt.h>
std::once_flag one_time_init_flag; std::once_flag one_time_init_flag;
bool one_time_init_success = false; bool one_time_init_success = false;

View File

@ -1,22 +1,19 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <mutex>
// SecureTransport has been deprecated in its entirety in favor of
// Network.framework, but that does not allow layering TLS on top of an
// arbitrary socket.
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <Security/SecureTransport.h>
#pragma GCC diagnostic pop
#endif
#include "core/hle/service/ssl/ssl_backend.h" #include "core/hle/service/ssl/ssl_backend.h"
#include "core/internal_network/network.h" #include "core/internal_network/network.h"
#include "core/internal_network/sockets.h" #include "core/internal_network/sockets.h"
#include <mutex>
#include <Security/SecureTransport.h>
// SecureTransport has been deprecated in its entirety in favor of
// Network.framework, but that does not allow layering TLS on top of an
// arbitrary socket.
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
namespace { namespace {
template <typename T> template <typename T>

View File

@ -10,7 +10,6 @@
#include "core/internal_network/network.h" #include "core/internal_network/network.h"
#include "core/internal_network/network_interface.h" #include "core/internal_network/network_interface.h"
#include "core/internal_network/socket_proxy.h" #include "core/internal_network/socket_proxy.h"
#include "network/network.h"
#if YUZU_UNIX #if YUZU_UNIX
#include <sys/socket.h> #include <sys/socket.h>

View File

@ -10,12 +10,10 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "core/internal_network/sockets.h" #include "core/internal_network/sockets.h"
#include "network/room_member.h" #include "network/network.h"
namespace Network { namespace Network {
class RoomNetwork;
class ProxySocket : public SocketBase { class ProxySocket : public SocketBase {
public: public:
explicit ProxySocket(RoomNetwork& room_network_) noexcept; explicit ProxySocket(RoomNetwork& room_network_) noexcept;

View File

@ -15,13 +15,12 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "core/internal_network/network.h" #include "core/internal_network/network.h"
#include "network/network.h"
// TODO: C++20 Replace std::vector usages with std::span // TODO: C++20 Replace std::vector usages with std::span
namespace Network { namespace Network {
struct ProxyPacket;
class SocketBase { class SocketBase {
public: public:
#ifdef YUZU_UNIX #ifdef YUZU_UNIX

View File

@ -153,7 +153,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
// Load NSO modules // Load NSO modules
modules.clear(); modules.clear();
const VAddr base_address{GetInteger(process.GetPageTable().GetCodeRegionStart())}; const VAddr base_address{GetInteger(process.PageTable().GetCodeRegionStart())};
VAddr next_load_addr{base_address}; VAddr next_load_addr{base_address};
const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
system.GetContentProvider()}; system.GetContentProvider()};

View File

@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
} }
codeset.memory = std::move(program_image); codeset.memory = std::move(program_image);
const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart());
process.LoadModule(std::move(codeset), base_address); process.LoadModule(std::move(codeset), base_address);
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address);

View File

@ -203,7 +203,7 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector<u8>& data)
// Load codeset for current process // Load codeset for current process
codeset.memory = std::move(program_image); codeset.memory = std::move(program_image);
process.LoadModule(std::move(codeset), process.GetPageTable().GetCodeRegionStart()); process.LoadModule(std::move(codeset), process.PageTable().GetCodeRegionStart());
return true; return true;
} }

View File

@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
modules.clear(); modules.clear();
// Load module // Load module
const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart());
if (!LoadModule(process, system, *file, base_address, true, true)) { if (!LoadModule(process, system, *file, base_address, true, true)) {
return {ResultStatus::ErrorLoadingNSO, {}}; return {ResultStatus::ErrorLoadingNSO, {}};
} }

View File

@ -31,10 +31,10 @@ struct Memory::Impl {
explicit Impl(Core::System& system_) : system{system_} {} explicit Impl(Core::System& system_) : system{system_} {}
void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
current_page_table = &process.GetPageTable().PageTableImpl(); current_page_table = &process.PageTable().PageTableImpl();
current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer(); current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
const std::size_t address_space_width = process.GetPageTable().GetAddressSpaceWidth(); const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth();
system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width); system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width);
} }
@ -186,7 +186,7 @@ struct Memory::Impl {
void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr, void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr,
const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer, const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer,
auto increment) { auto increment) {
const auto& page_table = process.GetPageTable().PageTableImpl(); const auto& page_table = process.PageTable().PageTableImpl();
std::size_t remaining_size = size; std::size_t remaining_size = size;
std::size_t page_index = addr >> YUZU_PAGEBITS; std::size_t page_index = addr >> YUZU_PAGEBITS;
std::size_t page_offset = addr & YUZU_PAGEMASK; std::size_t page_offset = addr & YUZU_PAGEMASK;
@ -808,7 +808,7 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b
bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
const Kernel::KProcess& process = *system.ApplicationProcess(); const Kernel::KProcess& process = *system.ApplicationProcess();
const auto& page_table = process.GetPageTable().PageTableImpl(); const auto& page_table = process.PageTable().PageTableImpl();
const size_t page = vaddr >> YUZU_PAGEBITS; const size_t page = vaddr >> YUZU_PAGEBITS;
if (page >= page_table.pointers.size()) { if (page >= page_table.pointers.size()) {
return false; return false;

View File

@ -199,7 +199,7 @@ void CheatEngine::Initialize() {
metadata.process_id = system.ApplicationProcess()->GetProcessId(); metadata.process_id = system.ApplicationProcess()->GetProcessId();
metadata.title_id = system.GetApplicationProcessProgramID(); metadata.title_id = system.GetApplicationProcessProgramID();
const auto& page_table = system.ApplicationProcess()->GetPageTable(); const auto& page_table = system.ApplicationProcess()->PageTable();
metadata.heap_extents = { metadata.heap_extents = {
.base = GetInteger(page_table.GetHeapRegionStart()), .base = GetInteger(page_table.GetHeapRegionStart()),
.size = page_table.GetHeapRegionSize(), .size = page_table.GetHeapRegionSize(),

View File

@ -117,8 +117,8 @@ json GetProcessorStateDataAuto(Core::System& system) {
arm.SaveContext(context); arm.SaveContext(context);
return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32", return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32",
GetInteger(process->GetPageTable().GetCodeRegionStart()), GetInteger(process->PageTable().GetCodeRegionStart()), context.sp,
context.sp, context.pc, context.pstate, context.cpu_registers); context.pc, context.pstate, context.cpu_registers);
} }
json GetBacktraceData(Core::System& system) { json GetBacktraceData(Core::System& system) {

View File

@ -442,11 +442,6 @@ void BufferCache<P>::UnbindComputeStorageBuffers() {
template <class P> template <class P>
void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, u32 cbuf_offset, void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, u32 cbuf_offset,
bool is_written) { bool is_written) {
if (ssbo_index >= channel_state->compute_storage_buffers.size()) [[unlikely]] {
LOG_ERROR(HW_GPU, "Storage buffer index {} exceeds maximum storage buffer count",
ssbo_index);
return;
}
channel_state->enabled_compute_storage_buffers |= 1U << ssbo_index; channel_state->enabled_compute_storage_buffers |= 1U << ssbo_index;
channel_state->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index; channel_state->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index;
@ -469,11 +464,6 @@ void BufferCache<P>::UnbindComputeTextureBuffers() {
template <class P> template <class P>
void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size,
PixelFormat format, bool is_written, bool is_image) { PixelFormat format, bool is_written, bool is_image) {
if (tbo_index >= channel_state->compute_texture_buffers.size()) [[unlikely]] {
LOG_ERROR(HW_GPU, "Texture buffer index {} exceeds maximum texture buffer count",
tbo_index);
return;
}
channel_state->enabled_compute_texture_buffers |= 1U << tbo_index; channel_state->enabled_compute_texture_buffers |= 1U << tbo_index;
channel_state->written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index; channel_state->written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index;
if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) {

View File

@ -67,7 +67,7 @@ constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4;
constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18; constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18;
constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8; constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8;
constexpr u32 NUM_STORAGE_BUFFERS = 16; constexpr u32 NUM_STORAGE_BUFFERS = 16;
constexpr u32 NUM_TEXTURE_BUFFERS = 32; constexpr u32 NUM_TEXTURE_BUFFERS = 16;
constexpr u32 NUM_STAGES = 5; constexpr u32 NUM_STAGES = 5;
using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>; using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>;

View File

@ -38,8 +38,8 @@ void RendererBase::RequestScreenshot(void* data, std::function<void(bool)> callb
LOG_ERROR(Render, "A screenshot is already requested or in progress, ignoring the request"); LOG_ERROR(Render, "A screenshot is already requested or in progress, ignoring the request");
return; return;
} }
auto async_callback{[callback_ = std::move(callback)](bool invert_y) { auto async_callback{[callback = std::move(callback)](bool invert_y) {
std::thread t{callback_, invert_y}; std::thread t{callback, invert_y};
t.detach(); t.detach();
}}; }};
renderer_settings.screenshot_bits = data; renderer_settings.screenshot_bits = data;

View File

@ -231,25 +231,24 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
} }
const bool in_parallel = thread_worker != nullptr; const bool in_parallel = thread_worker != nullptr;
const auto backend = device.GetShaderBackend(); const auto backend = device.GetShaderBackend();
auto func{[this, sources_ = std::move(sources), sources_spirv_ = std::move(sources_spirv), auto func{[this, sources = std::move(sources), sources_spirv = std::move(sources_spirv),
shader_notify, backend, in_parallel, shader_notify, backend, in_parallel,
force_context_flush](ShaderContext::Context*) mutable { force_context_flush](ShaderContext::Context*) mutable {
for (size_t stage = 0; stage < 5; ++stage) { for (size_t stage = 0; stage < 5; ++stage) {
switch (backend) { switch (backend) {
case Settings::ShaderBackend::GLSL: case Settings::ShaderBackend::GLSL:
if (!sources_[stage].empty()) { if (!sources[stage].empty()) {
source_programs[stage] = CreateProgram(sources_[stage], Stage(stage)); source_programs[stage] = CreateProgram(sources[stage], Stage(stage));
} }
break; break;
case Settings::ShaderBackend::GLASM: case Settings::ShaderBackend::GLASM:
if (!sources_[stage].empty()) { if (!sources[stage].empty()) {
assembly_programs[stage] = assembly_programs[stage] = CompileProgram(sources[stage], AssemblyStage(stage));
CompileProgram(sources_[stage], AssemblyStage(stage));
} }
break; break;
case Settings::ShaderBackend::SPIRV: case Settings::ShaderBackend::SPIRV:
if (!sources_spirv_[stage].empty()) { if (!sources_spirv[stage].empty()) {
source_programs[stage] = CreateProgram(sources_spirv_[stage], Stage(stage)); source_programs[stage] = CreateProgram(sources_spirv[stage], Stage(stage));
} }
break; break;
} }

View File

@ -288,9 +288,9 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const auto load_compute{[&](std::ifstream& file, FileEnvironment env) { const auto load_compute{[&](std::ifstream& file, FileEnvironment env) {
ComputePipelineKey key; ComputePipelineKey key;
file.read(reinterpret_cast<char*>(&key), sizeof(key)); file.read(reinterpret_cast<char*>(&key), sizeof(key));
queue_work([this, key, env_ = std::move(env), &state, &callback](Context* ctx) mutable { queue_work([this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {
ctx->pools.ReleaseContents(); ctx->pools.ReleaseContents();
auto pipeline{CreateComputePipeline(ctx->pools, key, env_, true)}; auto pipeline{CreateComputePipeline(ctx->pools, key, env, true)};
std::scoped_lock lock{state.mutex}; std::scoped_lock lock{state.mutex};
if (pipeline) { if (pipeline) {
compute_cache.emplace(key, std::move(pipeline)); compute_cache.emplace(key, std::move(pipeline));
@ -305,9 +305,9 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) { const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) {
GraphicsPipelineKey key; GraphicsPipelineKey key;
file.read(reinterpret_cast<char*>(&key), sizeof(key)); file.read(reinterpret_cast<char*>(&key), sizeof(key));
queue_work([this, key, envs_ = std::move(envs), &state, &callback](Context* ctx) mutable { queue_work([this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable {
boost::container::static_vector<Shader::Environment*, 5> env_ptrs; boost::container::static_vector<Shader::Environment*, 5> env_ptrs;
for (auto& env : envs_) { for (auto& env : envs) {
env_ptrs.push_back(&env); env_ptrs.push_back(&env);
} }
ctx->pools.ReleaseContents(); ctx->pools.ReleaseContents();

View File

@ -206,8 +206,8 @@ public:
const size_t sub_first_offset = static_cast<size_t>(first % 4) * GetQuadsNum(num_indices); const size_t sub_first_offset = static_cast<size_t>(first % 4) * GetQuadsNum(num_indices);
const size_t offset = const size_t offset =
(sub_first_offset + GetQuadsNum(first)) * 6ULL * BytesPerIndex(index_type); (sub_first_offset + GetQuadsNum(first)) * 6ULL * BytesPerIndex(index_type);
scheduler.Record([buffer_ = *buffer, index_type_, offset](vk::CommandBuffer cmdbuf) { scheduler.Record([buffer = *buffer, index_type_, offset](vk::CommandBuffer cmdbuf) {
cmdbuf.BindIndexBuffer(buffer_, offset, index_type_); cmdbuf.BindIndexBuffer(buffer, offset, index_type_);
}); });
} }
@ -528,18 +528,17 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bi
buffer_handles.push_back(handle); buffer_handles.push_back(handle);
} }
if (device.IsExtExtendedDynamicStateSupported()) { if (device.IsExtExtendedDynamicStateSupported()) {
scheduler.Record([bindings_ = std::move(bindings), scheduler.Record([bindings = std::move(bindings),
buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindVertexBuffers2EXT(bindings_.min_index, cmdbuf.BindVertexBuffers2EXT(
bindings_.max_index - bindings_.min_index, bindings.min_index, bindings.max_index - bindings.min_index, buffer_handles.data(),
buffer_handles_.data(), bindings_.offsets.data(), bindings.offsets.data(), bindings.sizes.data(), bindings.strides.data());
bindings_.sizes.data(), bindings_.strides.data());
}); });
} else { } else {
scheduler.Record([bindings_ = std::move(bindings), scheduler.Record([bindings = std::move(bindings),
buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindVertexBuffers(bindings_.min_index, bindings_.max_index - bindings_.min_index, cmdbuf.BindVertexBuffers(bindings.min_index, bindings.max_index - bindings.min_index,
buffer_handles_.data(), bindings_.offsets.data()); buffer_handles.data(), bindings.offsets.data());
}); });
} }
} }
@ -574,11 +573,11 @@ void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings<
for (u32 index = 0; index < bindings.buffers.size(); ++index) { for (u32 index = 0; index < bindings.buffers.size(); ++index) {
buffer_handles.push_back(bindings.buffers[index]->Handle()); buffer_handles.push_back(bindings.buffers[index]->Handle());
} }
scheduler.Record([bindings_ = std::move(bindings), scheduler.Record([bindings = std::move(bindings),
buffer_handles_ = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) {
cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast<u32>(buffer_handles_.size()), cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast<u32>(buffer_handles.size()),
buffer_handles_.data(), bindings_.offsets.data(), buffer_handles.data(), bindings.offsets.data(),
bindings_.sizes.data()); bindings.sizes.data());
}); });
} }

View File

@ -469,9 +469,9 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
ComputePipelineCacheKey key; ComputePipelineCacheKey key;
file.read(reinterpret_cast<char*>(&key), sizeof(key)); file.read(reinterpret_cast<char*>(&key), sizeof(key));
workers.QueueWork([this, key, env_ = std::move(env), &state, &callback]() mutable { workers.QueueWork([this, key, env = std::move(env), &state, &callback]() mutable {
ShaderPools pools; ShaderPools pools;
auto pipeline{CreateComputePipeline(pools, key, env_, state.statistics.get(), false)}; auto pipeline{CreateComputePipeline(pools, key, env, state.statistics.get(), false)};
std::scoped_lock lock{state.mutex}; std::scoped_lock lock{state.mutex};
if (pipeline) { if (pipeline) {
compute_cache.emplace(key, std::move(pipeline)); compute_cache.emplace(key, std::move(pipeline));
@ -500,10 +500,10 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
(key.state.dynamic_vertex_input != 0) != dynamic_features.has_dynamic_vertex_input) { (key.state.dynamic_vertex_input != 0) != dynamic_features.has_dynamic_vertex_input) {
return; return;
} }
workers.QueueWork([this, key, envs_ = std::move(envs), &state, &callback]() mutable { workers.QueueWork([this, key, envs = std::move(envs), &state, &callback]() mutable {
ShaderPools pools; ShaderPools pools;
boost::container::static_vector<Shader::Environment*, 5> env_ptrs; boost::container::static_vector<Shader::Environment*, 5> env_ptrs;
for (auto& env : envs_) { for (auto& env : envs) {
env_ptrs.push_back(&env); env_ptrs.push_back(&env);
} }
auto pipeline{CreateGraphicsPipeline(pools, key, MakeSpan(env_ptrs), auto pipeline{CreateGraphicsPipeline(pools, key, MakeSpan(env_ptrs),
@ -702,8 +702,8 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
if (!pipeline || pipeline_cache_filename.empty()) { if (!pipeline || pipeline_cache_filename.empty()) {
return pipeline; return pipeline;
} }
serialization_thread.QueueWork([this, key, env_ = std::move(env)] { serialization_thread.QueueWork([this, key, env = std::move(env)] {
SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env_}, SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
pipeline_cache_filename, CACHE_VERSION); pipeline_cache_filename, CACHE_VERSION);
}); });
return pipeline; return pipeline;

View File

@ -98,10 +98,10 @@ HostCounter::HostCounter(QueryCache& cache_, std::shared_ptr<HostCounter> depend
: HostCounterBase{std::move(dependency_)}, cache{cache_}, type{type_}, : HostCounterBase{std::move(dependency_)}, cache{cache_}, type{type_},
query{cache_.AllocateQuery(type_)}, tick{cache_.GetScheduler().CurrentTick()} { query{cache_.AllocateQuery(type_)}, tick{cache_.GetScheduler().CurrentTick()} {
const vk::Device* logical = &cache.GetDevice().GetLogical(); const vk::Device* logical = &cache.GetDevice().GetLogical();
cache.GetScheduler().Record([logical, query_ = query](vk::CommandBuffer cmdbuf) { cache.GetScheduler().Record([logical, query = query](vk::CommandBuffer cmdbuf) {
const bool use_precise = Settings::IsGPULevelHigh(); const bool use_precise = Settings::IsGPULevelHigh();
logical->ResetQueryPool(query_.first, query_.second, 1); logical->ResetQueryPool(query.first, query.second, 1);
cmdbuf.BeginQuery(query_.first, query_.second, cmdbuf.BeginQuery(query.first, query.second,
use_precise ? VK_QUERY_CONTROL_PRECISE_BIT : 0); use_precise ? VK_QUERY_CONTROL_PRECISE_BIT : 0);
}); });
} }
@ -111,9 +111,8 @@ HostCounter::~HostCounter() {
} }
void HostCounter::EndQuery() { void HostCounter::EndQuery() {
cache.GetScheduler().Record([query_ = query](vk::CommandBuffer cmdbuf) { cache.GetScheduler().Record(
cmdbuf.EndQuery(query_.first, query_.second); [query = query](vk::CommandBuffer cmdbuf) { cmdbuf.EndQuery(query.first, query.second); });
});
} }
u64 HostCounter::BlockingQuery(bool async) const { u64 HostCounter::BlockingQuery(bool async) const {

View File

@ -1412,7 +1412,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceS
} }
scheduler->RequestOutsideRenderPassOperationContext(); scheduler->RequestOutsideRenderPassOperationContext();
scheduler->Record([buffers = std::move(buffers_vector), image = *original_image, scheduler->Record([buffers = std::move(buffers_vector), image = *original_image,
aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { aspect_mask = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) {
const VkImageMemoryBarrier read_barrier{ const VkImageMemoryBarrier read_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr, .pNext = nullptr,
@ -1424,7 +1424,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceS
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image, .image = image,
.subresourceRange{ .subresourceRange{
.aspectMask = aspect_mask_, .aspectMask = aspect_mask,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = VK_REMAINING_MIP_LEVELS, .levelCount = VK_REMAINING_MIP_LEVELS,
.baseArrayLayer = 0, .baseArrayLayer = 0,
@ -1456,7 +1456,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceS
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image, .image = image,
.subresourceRange{ .subresourceRange{
.aspectMask = aspect_mask_, .aspectMask = aspect_mask,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = VK_REMAINING_MIP_LEVELS, .levelCount = VK_REMAINING_MIP_LEVELS,
.baseArrayLayer = 0, .baseArrayLayer = 0,

View File

@ -135,11 +135,11 @@ void RoomJson::Delete() {
LOG_ERROR(WebService, "Room must be registered to be deleted"); LOG_ERROR(WebService, "Room must be registered to be deleted");
return; return;
} }
Common::DetachedTasks::AddTask([host_{this->host}, username_{this->username}, Common::DetachedTasks::AddTask(
token_{this->token}, room_id_{this->room_id}]() { [host{this->host}, username{this->username}, token{this->token}, room_id{this->room_id}]() {
// create a new client here because the this->client might be destroyed. // create a new client here because the this->client might be destroyed.
Client{host_, username_, token_}.DeleteJson(fmt::format("/lobby/{}", room_id_), "", false); Client{host, username, token}.DeleteJson(fmt::format("/lobby/{}", room_id), "", false);
}); });
} }
} // namespace WebService } // namespace WebService

View File

@ -235,7 +235,7 @@ GameListWorker::~GameListWorker() = default;
void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
using namespace FileSys; using namespace FileSys;
const auto& cache = system.GetContentProviderUnion(); const auto& cache = dynamic_cast<ContentProviderUnion&>(system.GetContentProvider());
auto installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application, auto installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application,
ContentRecordType::Program); ContentRecordType::Program);