Compare commits

..

1 Commits

Author SHA1 Message Date
yuzubot
b7d1869b24 Android #13 2023-07-19 00:59:17 +00:00
114 changed files with 2976 additions and 3038 deletions

View File

@@ -35,7 +35,7 @@ DESTDIR="$PWD/AppDir" ninja install
rm -vf AppDir/usr/bin/yuzu-cmd AppDir/usr/bin/yuzu-tester
# 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://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/exec-x86_64.so
# Set executable bit

View File

@@ -12,7 +12,7 @@ steps:
inputs:
targetType: 'filePath'
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'
- task: MSBuild@1
displayName: 'Build'

View File

@@ -136,22 +136,6 @@ if (YUZU_USE_BUNDLED_VCPKG)
endif()
endif()
if (MSVC)
set(VCPKG_DOWNLOADS_PATH ${PROJECT_SOURCE_DIR}/externals/vcpkg/downloads)
set(NASM_VERSION "2.16.01")
set(NASM_DESTINATION_PATH ${VCPKG_DOWNLOADS_PATH}/nasm-${NASM_VERSION}-win64.zip)
set(NASM_DOWNLOAD_URL "https://github.com/yuzu-emu/ext-windows-bin/raw/master/nasm/nasm-${NASM_VERSION}-win64.zip")
if (NOT EXISTS ${NASM_DESTINATION_PATH})
file(DOWNLOAD ${NASM_DOWNLOAD_URL} ${NASM_DESTINATION_PATH} SHOW_PROGRESS STATUS NASM_STATUS)
if (NOT NASM_STATUS EQUAL 0)
# Warn and not fail since vcpkg is supposed to download this package for us in the first place
message(WARNING "External nasm vcpkg package download from ${NASM_DOWNLOAD_URL} failed with status ${NASM_STATUS}")
endif()
endif()
endif()
if (YUZU_TESTS)
list(APPEND VCPKG_MANIFEST_FEATURES "yuzu-tests")
endif()
@@ -305,7 +289,7 @@ find_package(Boost 1.79.0 REQUIRED context)
find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
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(nlohmann_json 3.8 REQUIRED)
find_package(Opus 1.3 MODULE)

View File

@@ -20,7 +20,9 @@
#include <cstdlib>
#include <cstring>
#include <functional>
#include <numeric>
#include <utility>
#include <vector>
using namespace llvm;
using namespace llvm::itanium_demangle;
@@ -79,8 +81,8 @@ struct DumpVisitor {
}
void printStr(const char *S) { fprintf(stderr, "%s", S); }
void print(std::string_view SV) {
fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.data());
void print(StringView SV) {
fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
}
void print(const Node *N) {
if (N)
@@ -88,6 +90,14 @@ struct DumpVisitor {
else
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) {
++Depth;
printStr("{");
@@ -106,11 +116,13 @@ struct DumpVisitor {
// Overload used when T is exactly 'bool', not merely convertible to 'bool'.
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);
}
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);
}
@@ -173,50 +185,6 @@ struct DumpVisitor {
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() {
printStr("\n");
@@ -366,21 +334,36 @@ public:
using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
char *llvm::itaniumDemangle(std::string_view MangledName) {
if (MangledName.empty())
char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
size_t *N, int *Status) {
if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
if (Status)
*Status = demangle_invalid_args;
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();
if (!AST)
return nullptr;
OutputBuffer OB;
assert(Parser.ForwardTemplateRefs.empty());
AST->print(OB);
OB += '\0';
return OB.getBuffer();
if (AST == nullptr)
InternalStatus = demangle_invalid_mangled_name;
else if (!initializeOutputStream(Buf, N, S, 1024))
InternalStatus = demangle_memory_alloc_failure;
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()
@@ -413,12 +396,14 @@ bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
}
static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
OutputBuffer OB(Buf, N);
RootNode->print(OB);
OB += '\0';
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
RootNode->print(S);
S += '\0';
if (N != nullptr)
*N = OB.getCurrentPosition();
return OB.getBuffer();
*N = S.getCurrentPosition();
return S.getBuffer();
}
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:
Name = static_cast<const AbiTagAttr *>(Name)->Base;
continue;
case Node::KModuleEntity:
Name = static_cast<const ModuleEntity *>(Name)->Name;
case Node::KStdQualifiedName:
Name = static_cast<const StdQualifiedName *>(Name)->Child;
continue;
case Node::KNestedName:
Name = static_cast<const NestedName *>(Name)->Name;
@@ -456,7 +441,9 @@ char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
return nullptr;
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
OutputBuffer OB(Buf, N);
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
KeepGoingLocalFunction:
while (true) {
@@ -471,27 +458,27 @@ char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
break;
}
if (Name->getKind() == Node::KModuleEntity)
Name = static_cast<const ModuleEntity *>(Name)->Name;
switch (Name->getKind()) {
case Node::KStdQualifiedName:
S += "std";
break;
case Node::KNestedName:
static_cast<const NestedName *>(Name)->Qual->print(OB);
static_cast<const NestedName *>(Name)->Qual->print(S);
break;
case Node::KLocalName: {
auto *LN = static_cast<const LocalName *>(Name);
LN->Encoding->print(OB);
OB += "::";
LN->Encoding->print(S);
S += "::";
Name = LN->Entity;
goto KeepGoingLocalFunction;
}
default:
break;
}
OB += '\0';
S += '\0';
if (N != nullptr)
*N = OB.getCurrentPosition();
return OB.getBuffer();
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
@@ -507,15 +494,17 @@ char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
return nullptr;
NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
OutputBuffer OB(Buf, N);
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
OB += '(';
Params.printWithComma(OB);
OB += ')';
OB += '\0';
S += '(';
Params.printWithComma(S);
S += ')';
S += '\0';
if (N != nullptr)
*N = OB.getCurrentPosition();
return OB.getBuffer();
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::getFunctionReturnType(
@@ -523,16 +512,18 @@ char *ItaniumPartialDemangler::getFunctionReturnType(
if (!isFunction())
return nullptr;
OutputBuffer OB(Buf, N);
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
if (const Node *Ret =
static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
Ret->print(OB);
Ret->print(S);
OB += '\0';
S += '\0';
if (N != nullptr)
*N = OB.getCurrentPosition();
return OB.getBuffer();
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
@@ -572,8 +563,8 @@ bool ItaniumPartialDemangler::isCtorOrDtor() const {
case Node::KNestedName:
N = static_cast<const NestedName *>(N)->Name;
break;
case Node::KModuleEntity:
N = static_cast<const ModuleEntity *>(N)->Name;
case Node::KStdQualifiedName:
N = static_cast<const StdQualifiedName *>(N)->Child;
break;
}
}

View File

@@ -12,7 +12,6 @@
#include <cstddef>
#include <string>
#include <string_view>
namespace llvm {
/// This is a llvm local version of __cxa_demangle. Other than the name and
@@ -30,10 +29,9 @@ enum : int {
demangle_success = 0,
};
/// Returns a non-NULL pointer to a NUL-terminated C style string
/// that should be explicitly freed, if successful. Otherwise, may return
/// nullptr if mangled_name is not a valid mangling or is nullptr.
char *itaniumDemangle(std::string_view mangled_name);
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
int *status);
enum MSDemangleFlags {
MSDF_None = 0,
@@ -42,34 +40,10 @@ enum MSDemangleFlags {
MSDF_NoCallingConvention = 1 << 2,
MSDF_NoReturnType = 1 << 3,
MSDF_NoMemberType = 1 << 4,
MSDF_NoVariableType = 1 << 5,
};
/// 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,
char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n,
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
/// (typically an intermediate stage in itaniumDemangle) and querying certain
/// properties or partially printing the demangled name.
@@ -85,7 +59,7 @@ struct ItaniumPartialDemangler {
bool partialDemangle(const char *MangledName);
/// 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;
/// Get the base name of a function. This doesn't include trailing template
@@ -121,7 +95,6 @@ struct ItaniumPartialDemangler {
bool isSpecialName() const;
~ItaniumPartialDemangler();
private:
void *RootNode;
void *Context;

View File

@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEMANGLE_DEMANGLECONFIG_H
#define LLVM_DEMANGLE_DEMANGLECONFIG_H
#ifndef LLVM_DEMANGLE_COMPILER_H
#define LLVM_DEMANGLE_COMPILER_H
#ifndef __has_feature
#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) -*-===//
// Do not edit! See README.txt.
//===--- StringView.h -------------------------------------------*- C++ -*-===//
//
// 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
@@ -8,9 +8,6 @@
//===----------------------------------------------------------------------===//
//
// 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
#include "DemangleConfig.h"
#include <algorithm>
#include <cassert>
#include <cstring>
@@ -39,23 +37,29 @@ public:
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
StringView() : First(nullptr), Last(nullptr) {}
StringView substr(size_t Pos, size_t Len = npos) const {
assert(Pos <= size());
if (Len > size() - Pos)
Len = size() - Pos;
return StringView(begin() + Pos, Len);
StringView substr(size_t From) const {
return StringView(begin() + From, size() - From);
}
size_t find(char C, size_t From = 0) const {
size_t FindBegin = std::min(From, size());
// Avoid calling memchr with nullptr.
if (From < size()) {
if (FindBegin < size()) {
// 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 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 {
if (N >= size())
N = size();
@@ -102,7 +106,7 @@ public:
bool startsWith(StringView Str) const {
if (Str.size() > size())
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); }
@@ -115,7 +119,7 @@ public:
inline bool operator==(const StringView &LHS, const StringView &RHS) {
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

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) -*-===//
// Do not edit! See README.txt.
//===--- Utility.h ----------------------------------------------*- C++ -*-===//
//
// 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
@@ -7,83 +7,70 @@
//
//===----------------------------------------------------------------------===//
//
// Provide some utility classes for use in the demangler.
// 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.
// Provide some utility classes for use in the demangler(s).
//
//===----------------------------------------------------------------------===//
#ifndef DEMANGLE_UTILITY_H
#define DEMANGLE_UTILITY_H
#include "DemangleConfig.h"
#include <array>
#include <cassert>
#include "StringView.h"
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <iterator>
#include <limits>
#include <string_view>
DEMANGLE_NAMESPACE_BEGIN
// Stream that AST nodes write their string representation into after the AST
// has been parsed.
class OutputBuffer {
char *Buffer = nullptr;
size_t CurrentPosition = 0;
size_t BufferCapacity = 0;
class OutputStream {
char *Buffer;
size_t CurrentPosition;
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) {
size_t Need = N + CurrentPosition;
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;
if (N + CurrentPosition >= BufferCapacity) {
BufferCapacity *= 2;
if (BufferCapacity < Need)
BufferCapacity = Need;
if (BufferCapacity < N + CurrentPosition)
BufferCapacity = N + CurrentPosition;
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
if (Buffer == nullptr)
std::terminate();
}
}
OutputBuffer &writeUnsigned(uint64_t N, bool isNeg = false) {
std::array<char, 21> Temp;
char *TempPtr = Temp.data() + Temp.size();
void writeUnsigned(uint64_t N, bool isNeg = false) {
// Handle special case...
if (N == 0) {
*this << '0';
return;
}
// Output at least one character.
do {
*--TempPtr = char('0' + N % 10);
char Temp[21];
char *TempPtr = std::end(Temp);
while (N) {
*--TempPtr = '0' + char(N % 10);
N /= 10;
} while (N);
}
// Add negative sign.
// Add negative sign...
if (isNeg)
*--TempPtr = '-';
return operator+=(
std::string_view(TempPtr, Temp.data() + Temp.size() - TempPtr));
this->operator<<(StringView(TempPtr, std::end(Temp)));
}
public:
OutputBuffer(char *StartBuf, size_t Size)
: Buffer(StartBuf), BufferCapacity(Size) {}
OutputBuffer(char *StartBuf, size_t *SizePtr)
: OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {}
OutputBuffer() = default;
// Non-copyable
OutputBuffer(const OutputBuffer &) = delete;
OutputBuffer &operator=(const OutputBuffer &) = delete;
operator std::string_view() const {
return std::string_view(Buffer, CurrentPosition);
OutputStream(char *StartBuf, size_t Size)
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
OutputStream() = default;
void reset(char *Buffer_, size_t BufferCapacity_) {
CurrentPosition = 0;
Buffer = Buffer_;
BufferCapacity = BufferCapacity_;
}
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
@@ -91,116 +78,115 @@ public:
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
/// When zero, we're printing template args and '>' needs to be parenthesized.
/// Use a counter so we can simply increment inside parentheses.
unsigned GtIsGt = 1;
bool isGtInsideTemplateArgs() const { return GtIsGt == 0; }
void printOpen(char Open = '(') {
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;
}
OutputStream &operator+=(StringView R) {
size_t Size = R.size();
if (Size == 0)
return *this;
grow(Size);
std::memmove(Buffer + CurrentPosition, R.begin(), Size);
CurrentPosition += Size;
return *this;
}
OutputBuffer &operator+=(char C) {
OutputStream &operator+=(char C) {
grow(1);
Buffer[CurrentPosition++] = C;
return *this;
}
OutputBuffer &prepend(std::string_view R) {
size_t Size = R.size();
OutputStream &operator<<(StringView R) { return (*this += R); }
grow(Size);
std::memmove(Buffer + Size, Buffer, CurrentPosition);
std::memcpy(Buffer, &*R.begin(), Size);
CurrentPosition += Size;
OutputStream &operator<<(char C) { return (*this += C); }
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;
}
OutputBuffer &operator<<(std::string_view R) { return (*this += R); }
OutputBuffer &operator<<(char C) { return (*this += C); }
OutputBuffer &operator<<(long long N) {
return writeUnsigned(static_cast<unsigned long long>(std::abs(N)), N < 0);
OutputStream &operator<<(unsigned long long N) {
writeUnsigned(N, false);
return *this;
}
OutputBuffer &operator<<(unsigned long long N) {
return writeUnsigned(N, false);
}
OutputBuffer &operator<<(long N) {
OutputStream &operator<<(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));
}
OutputBuffer &operator<<(int N) {
OutputStream &operator<<(int 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));
}
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; }
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
char back() const {
assert(CurrentPosition);
return Buffer[CurrentPosition - 1];
return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
}
bool empty() const { return CurrentPosition == 0; }
char *getBuffer() { return Buffer; }
char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
size_t getBufferCapacity() const { return BufferCapacity; }
size_t getBufferCapacity() { return BufferCapacity; }
};
template <class T> class ScopedOverride {
T &Loc;
T Original;
template <class T> class SwapAndRestore {
T &Restore;
T OriginalValue;
bool ShouldRestore = true;
public:
ScopedOverride(T &Loc_) : ScopedOverride(Loc_, Loc_) {}
SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
ScopedOverride(T &Loc_, T NewVal) : Loc(Loc_), Original(Loc_) {
Loc_ = std::move(NewVal);
SwapAndRestore(T &Restore_, T 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;
ScopedOverride &operator=(const ScopedOverride &) = delete;
void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
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
#endif

View File

@@ -449,7 +449,7 @@ private:
loader->ReadTitle(entry.title);
loader->ReadIcon(entry.icon);
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();
} else {
entry.isHomebrew = false;

View File

@@ -235,6 +235,26 @@
<string name="region_korea">Korea</string>
<string name="region_taiwan">Taiwan</string>
<!-- Language Names -->
<string name="language_japanese">Japanisch (日本語)</string>
<string name="language_english">Englisch</string>
<string name="language_french">Französisch (Français)</string>
<string name="langauge_german">Deutsch (German)</string>
<string name="language_italian">Italienisch (Italiano)</string>
<string name="language_spanish">Spanisch (Español)</string>
<string name="language_chinese">Chinesisch (简体中文)</string>
<string name="language_korean">Koreanisch (한국어)</string>
<string name="language_dutch">Niederländisch (Nederlands)</string>
<string name="language_portuguese">Portugiesisch (Português)</string>
<string name="language_russian">Russisch (Русский)</string>
<string name="language_taiwanese">Taiwanesisch (台湾)</string>
<string name="language_british_english">Britisches Englisch</string>
<string name="language_canadian_french">Kanadisches Französisch (Français canadien)</string>
<string name="language_latin_american_spanish">Lateinamerikanisches Spanisch (Español latinoamericano)</string>
<string name="language_simplified_chinese">Vereinfachtes Chinesisch (简体中文)</string>
<string name="language_traditional_chinese">Traditionelles Chinesisch (正體中文)</string>
<string name="language_brazilian_portuguese">Brasilianisches Portugiesisch (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
<string name="renderer_none">Keiner</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Taiwán</string>
<!-- Language Names -->
<string name="language_japanese">Japonés (日本語)</string>
<string name="language_english">Inglés (English)</string>
<string name="language_french">Francés (Français)</string>
<string name="langauge_german">Alemán (deutsch)</string>
<string name="language_italian">Italiano (Italiano)</string>
<string name="language_spanish">Español (Español)</string>
<string name="language_chinese">Chino (简体中文)</string>
<string name="language_korean">Coreano (한국어)</string>
<string name="language_dutch">Holandés (nederlands)</string>
<string name="language_portuguese">Portugués (Português)</string>
<string name="language_russian">Ruso (Русский)</string>
<string name="language_taiwanese">Taiwanés (台湾)</string>
<string name="language_british_english">Inglés británico</string>
<string name="language_canadian_french">Francés Canadiense (Français canadien)</string>
<string name="language_latin_american_spanish">Español Latinoamericano (Español latinoamericano)</string>
<string name="language_simplified_chinese">Chino Simplificado (简体中文)</string>
<string name="language_traditional_chinese">Chino tradicional (正體中文)</string>
<string name="language_brazilian_portuguese">Portugués Brasileño (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Taïwan</string>
<!-- Language Names -->
<string name="language_japanese">Japonais (日本語)</string>
<string name="language_english">Anglais</string>
<string name="language_french">Français (Français)</string>
<string name="langauge_german">Allemand (Deutsch)</string>
<string name="language_italian">Italien (Italiano)</string>
<string name="language_spanish">Espagnol (Español)</string>
<string name="language_chinese">Chinois (简体中文)</string>
<string name="language_korean">Coréen (한국어)</string>
<string name="language_dutch">Néerlandais (Nederlands)</string>
<string name="language_portuguese">Portugais (Português)</string>
<string name="language_russian">Russe (Русский)</string>
<string name="language_taiwanese">Taïwanais (台湾)</string>
<string name="language_british_english">Anglais Britannique</string>
<string name="language_canadian_french">Français canadien (Français canadien)</string>
<string name="language_latin_american_spanish">Espagnol latino-américain (Español latinoamericano)</string>
<string name="language_simplified_chinese">Chinois simplifié (简体中文)</string>
<string name="language_traditional_chinese">Chinois Traditionnel (正體中文)</string>
<string name="language_brazilian_portuguese">Portugais brésilien (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Taiwan</string>
<!-- Language Names -->
<string name="language_japanese">Giapponese (日本語)</string>
<string name="language_english">Inglese (English)</string>
<string name="language_french">Francese (Français)</string>
<string name="langauge_german">Tedesco (Deutsch)</string>
<string name="language_italian">Italiano (Italiano)</string>
<string name="language_spanish">Spagnolo (Español)</string>
<string name="language_chinese">Cinese (简体中文)</string>
<string name="language_korean">Coreano (한국어)</string>
<string name="language_dutch">Olandese (Nederlands)</string>
<string name="language_portuguese">Portoghese (Português)</string>
<string name="language_russian">Russo (Русский)</string>
<string name="language_taiwanese">Taiwanese (台湾)</string>
<string name="language_british_english">Inglese britannico</string>
<string name="language_canadian_french">Francese Canadese (Français canadien)</string>
<string name="language_latin_american_spanish">Spagnolo Latino Americano (Español latinoamericano)</string>
<string name="language_simplified_chinese">Cinese Semplificato (简体中文)</string>
<string name="language_traditional_chinese">Cinese tradizionale (正體中文)</string>
<string name="language_brazilian_portuguese">Portoghese (Português)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -239,6 +239,24 @@
<string name="region_taiwan">台湾</string>
<!-- Language Names -->
<string name="language_japanese">日本語</string>
<string name="language_english">英語</string>
<string name="language_french">フランス語 (Français)</string>
<string name="langauge_german">ドイツ語 (Deutsch)</string>
<string name="language_italian">イタリア語 (Italiano)</string>
<string name="language_spanish">スペイン語 (Español)</string>
<string name="language_chinese">中国語 (简体中文)</string>
<string name="language_korean">韓国語 (한국어)</string>
<string name="language_dutch">オランダ語 (Nederlands)</string>
<string name="language_portuguese">ポルトガル語 (Português)</string>
<string name="language_russian">ロシア語 (Русский)</string>
<string name="language_taiwanese">台湾語 (台湾)</string>
<string name="language_british_english">イギリス英語</string>
<string name="language_canadian_french">フランス語(カナダ) (Français canadien)</string>
<string name="language_latin_american_spanish">スペイン語(ラテンアメリカ) (Español latinoamericano)</string>
<string name="language_simplified_chinese">中国語 (简体中文)</string>
<string name="language_traditional_chinese">繁体字中国語 (正體中文)</string>
<string name="language_brazilian_portuguese">ポルトガル語(ブラジル) (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">타이완</string>
<!-- Language Names -->
<string name="language_japanese">일본어 (日本語)</string>
<string name="language_english">영어 (English)</string>
<string name="language_french">프랑스어 (Français)</string>
<string name="langauge_german">독일어(Deutsch)</string>
<string name="language_italian">이탈리아어 (Italiano)</string>
<string name="language_spanish">스페인어 (Español)</string>
<string name="language_chinese">중국어 (简体中文)</string>
<string name="language_korean">한국어 (Korean)</string>
<string name="language_dutch">네덜란드어 (Nederlands)</string>
<string name="language_portuguese">포르투갈어 (Português)</string>
<string name="language_russian">러시아어 (Русский)</string>
<string name="language_taiwanese">대만어 (台湾)</string>
<string name="language_british_english">영어 (British English)</string>
<string name="language_canadian_french">캐나다 프랑스어 (Français canadien)</string>
<string name="language_latin_american_spanish">라틴 아메리카 스페인어 (Español latinoamericano)</string>
<string name="language_simplified_chinese">중국어 간체 (简体中文)</string>
<string name="language_traditional_chinese">중국어 번체 (正體中文)</string>
<string name="language_brazilian_portuguese">브라질 포르투갈어 (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">불칸</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Taiwan</string>
<!-- Language Names -->
<string name="language_japanese">Japansk (日本語)</string>
<string name="language_english">Engelsk</string>
<string name="language_french">Fransk (Français)</string>
<string name="langauge_german">Tysk (Deutsch)</string>
<string name="language_italian">Italiensk (Italiano)</string>
<string name="language_spanish">Spansk (Español)</string>
<string name="language_chinese">Kinesisk (简体中文)</string>
<string name="language_korean">Koreansk (한국어)</string>
<string name="language_dutch">Nederlandsk (Nederlands)</string>
<string name="language_portuguese">Portugisisk (Português)</string>
<string name="language_russian">Russisk (Русский)</string>
<string name="language_taiwanese">Taiwansk (台湾)</string>
<string name="language_british_english">Britisk Engelsk</string>
<string name="language_canadian_french">Kanadisk fransk (Français canadien)</string>
<string name="language_latin_american_spanish">Latinamerikansk spansk (Español latinoamericano)</string>
<string name="language_simplified_chinese">Forenklet kinesisk (简体中文)</string>
<string name="language_traditional_chinese">Tradisjonell Kinesisk (正體中文)</string>
<string name="language_brazilian_portuguese">Brasiliansk portugisisk (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Tajwan</string>
<!-- Language Names -->
<string name="language_japanese">Japoński (日本語)</string>
<string name="language_english">Angielski</string>
<string name="language_french">Francuski (Francja)</string>
<string name="langauge_german">Niemiecki (Niemcy)</string>
<string name="language_italian">Włoski (Włochy)</string>
<string name="language_spanish">Hiszpański (Hiszpania)</string>
<string name="language_chinese">Chiński (简体中文)</string>
<string name="language_korean">Koreański (한국어)</string>
<string name="language_dutch">Duński (Holandia)</string>
<string name="language_portuguese">Portugalski (Portugalia)</string>
<string name="language_russian">Rosyjski (Русский)</string>
<string name="language_taiwanese">Tajwański (台湾)</string>
<string name="language_british_english">Angielski Brytyjski</string>
<string name="language_canadian_french">Francuski (Kanada)</string>
<string name="language_latin_american_spanish">Hiszpański (Ameryka Latynoska)</string>
<string name="language_simplified_chinese">Chiński uproszczony (简体中文)</string>
<string name="language_traditional_chinese">Chiński tradycyjny (正體中文)</string>
<string name="language_brazilian_portuguese">Portugalski (Brazylia)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Taiwan</string>
<!-- Language Names -->
<string name="language_japanese">Japônes (日本語)</string>
<string name="language_english">Português do Brasil</string>
<string name="language_french">Francês (Français)</string>
<string name="langauge_german">Alemão (Deutsch)</string>
<string name="language_italian">Italiano (Italiano)</string>
<string name="language_spanish">Espanhol (Español)</string>
<string name="language_chinese">Mandarim (简体中文)</string>
<string name="language_korean">Coreano (한국어)</string>
<string name="language_dutch">Holandês (Nederlands)</string>
<string name="language_portuguese">Português (Português)</string>
<string name="language_russian">Russo (Русский)</string>
<string name="language_taiwanese">Taiwanês (台湾)</string>
<string name="language_british_english">Inglês britânico (British English)</string>
<string name="language_canadian_french">Fracês Canadiano (Français canadien)</string>
<string name="language_latin_american_spanish">Espanhol da América Latina (Español latino-americano)</string>
<string name="language_simplified_chinese">Chinês Simplificado (简体中文)</string>
<string name="language_traditional_chinese">Chinês tradicional (正體中文)</string>
<string name="language_brazilian_portuguese">Português do Brasil (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulcano</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Taiwan</string>
<!-- Language Names -->
<string name="language_japanese">Japonês (日本語)</string>
<string name="language_english">Inglês</string>
<string name="language_french">Francês (Français)</string>
<string name="langauge_german">Alemão (Deutsch)</string>
<string name="language_italian">Italiano (Italiano)</string>
<string name="language_spanish">Espanhol (Español)</string>
<string name="language_chinese">Chinês simplificado (简体中文)</string>
<string name="language_korean">Coreano (한국어)</string>
<string name="language_dutch">Holandês (Nederlands)</string>
<string name="language_portuguese">Português (Português)</string>
<string name="language_russian">Russo (Русский)</string>
<string name="language_taiwanese">Taiwanês (台湾)</string>
<string name="language_british_english">Inglês Britânico</string>
<string name="language_canadian_french">Fracês Canadiano (Français canadien)</string>
<string name="language_latin_american_spanish">Espanhol da América Latina (Español latino-americano)</string>
<string name="language_simplified_chinese">Chinês Simplificado (简体中文)</string>
<string name="language_traditional_chinese">Chinês Tradicional (正 體 中文)</string>
<string name="language_brazilian_portuguese">Português do Brasil (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulcano</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Тайвань</string>
<!-- Language Names -->
<string name="language_japanese">Японский (日本語)</string>
<string name="language_english">Английский (English)</string>
<string name="language_french">Французский (Français)</string>
<string name="langauge_german">Немецкий (Deutsch)</string>
<string name="language_italian">Итальянский (Italiano)</string>
<string name="language_spanish">Испанский (Español)</string>
<string name="language_chinese">Китайский (简体中文)</string>
<string name="language_korean">Корейский (한국어)</string>
<string name="language_dutch">Голландский (Nederlands)</string>
<string name="language_portuguese">Португальский (Português)</string>
<string name="language_russian">Русский</string>
<string name="language_taiwanese">Тайваньский (台湾)</string>
<string name="language_british_english">Британский английский</string>
<string name="language_canadian_french">Канадский французский (Français canadien)</string>
<string name="language_latin_american_spanish">Латиноамериканский испанский (Español latinoamericano)</string>
<string name="language_simplified_chinese">Упрощенный китайский (简体中文)</string>
<string name="language_traditional_chinese">Традиционный китайский (正體中文)</string>
<string name="language_brazilian_portuguese">Бразильский португальский (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">Тайвань</string>
<!-- Language Names -->
<string name="language_japanese">Японська (日本語)</string>
<string name="language_english">Англійська (English)</string>
<string name="language_french">Французька (Français)</string>
<string name="langauge_german">Німецька (Deutsch)</string>
<string name="language_italian">Італійська (Italiano)</string>
<string name="language_spanish">Іспанська (Español)</string>
<string name="language_chinese">Китайскька (简体中文)</string>
<string name="language_korean">Корейська (한국어)</string>
<string name="language_dutch">Голландська (Nederlands)</string>
<string name="language_portuguese">Португальська (Português)</string>
<string name="language_russian">Російська (Русский)</string>
<string name="language_taiwanese">Тайванська (台湾)</string>
<string name="language_british_english">Британська англійська</string>
<string name="language_canadian_french">Канадська французька (Français canadien)</string>
<string name="language_latin_american_spanish">Латиноамериканська іспанська (Español latinoamericano)</string>
<string name="language_simplified_chinese">Спрощена китайська (简体中文)</string>
<string name="language_traditional_chinese">Традиційна китайська (正體中文)</string>
<string name="language_brazilian_portuguese">Бразильська португальська (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">中国台湾</string>
<!-- Language Names -->
<string name="language_japanese">日语 (日本語)</string>
<string name="language_english">英语 (English)</string>
<string name="language_french">法语 (Français)</string>
<string name="langauge_german">德语 (Deutsch)</string>
<string name="language_italian">意大利语 (Italiano)</string>
<string name="language_spanish">西班牙语 (Español)</string>
<string name="language_chinese">中文 (简体中文)</string>
<string name="language_korean">韩语 (한국어)</string>
<string name="language_dutch">荷兰语 (Nederlands)</string>
<string name="language_portuguese">葡萄牙语 (Português)</string>
<string name="language_russian">俄语 (Русский)</string>
<string name="language_taiwanese">台湾中文 (台灣)</string>
<string name="language_british_english">英式英语</string>
<string name="language_canadian_french">加拿大法语 (Français canadien)</string>
<string name="language_latin_american_spanish">拉丁美洲西班牙语 (Español latinoamericano)</string>
<string name="language_simplified_chinese">简体中文 (简体中文)</string>
<string name="language_traditional_chinese">繁体中文 (正體中文)</string>
<string name="language_brazilian_portuguese">巴西葡萄牙语 (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -241,6 +241,24 @@
<string name="region_taiwan">台灣</string>
<!-- Language Names -->
<string name="language_japanese">日文 (日本語)</string>
<string name="language_english">英文</string>
<string name="language_french">法文 (Français)</string>
<string name="langauge_german">德文 (Deutsch)</string>
<string name="language_italian">義大利文 (Italiano)</string>
<string name="language_spanish">西班牙文 (Español)</string>
<string name="language_chinese">中文 (简体中文)</string>
<string name="language_korean">韓文 (한국어)</string>
<string name="language_dutch">荷蘭文 (Nederlands)</string>
<string name="language_portuguese">葡萄牙文 (Português)</string>
<string name="language_russian">俄文 (Русский)</string>
<string name="language_taiwanese">台文 (台灣)</string>
<string name="language_british_english">英式英文</string>
<string name="language_canadian_french">加拿大法文 (Français canadien)</string>
<string name="language_latin_american_spanish">拉丁美洲西班牙文 (Español latinoamericano)</string>
<string name="language_simplified_chinese">簡體中文 (简体中文)</string>
<string name="language_traditional_chinese">正體中文 (正體中文)</string>
<string name="language_brazilian_portuguese">巴西葡萄牙文 (Português do Brasil)</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>

View File

@@ -287,24 +287,24 @@
<string name="region_taiwan">Taiwan</string>
<!-- Language Names -->
<string name="language_japanese" translatable="false">日本語</string>
<string name="language_english" translatable="false">English</string>
<string name="language_french" translatable="false">Français</string>
<string name="langauge_german" translatable="false">Deutsch</string>
<string name="language_italian" translatable="false">Italiano</string>
<string name="language_spanish" translatable="false">Español</string>
<string name="language_chinese" translatable="false">简体中文</string>
<string name="language_korean" translatable="false">한국어</string>
<string name="language_dutch" translatable="false">Nederlands</string>
<string name="language_portuguese" translatable="false">Português</string>
<string name="language_russian" translatable="false">Русский</string>
<string name="language_taiwanese" translatable="false">台湾</string>
<string name="language_british_english" translatable="false">British English</string>
<string name="language_canadian_french" translatable="false">Français canadien</string>
<string name="language_latin_american_spanish" translatable="false">Español latinoamericano</string>
<string name="language_simplified_chinese" translatable="false">简体中文</string>
<string name="language_traditional_chinese" translatable="false">正體中文</string>
<string name="language_brazilian_portuguese" translatable="false">Português do Brasil</string>
<string name="language_japanese">Japanese (日本語)</string>
<string name="language_english">English</string>
<string name="language_french">French (Français)</string>
<string name="langauge_german">German (Deutsch)</string>
<string name="language_italian">Italian (Italiano)</string>
<string name="language_spanish">Spanish (Español)</string>
<string name="language_chinese">Chinese (简体中文)</string>
<string name="language_korean">Korean (한국어)</string>
<string name="language_dutch">Dutch (Nederlands)</string>
<string name="language_portuguese">Portuguese (Português)</string>
<string name="language_russian">Russian (Русский)</string>
<string name="language_taiwanese">Taiwanese (台湾)</string>
<string name="language_british_english">British English</string>
<string name="language_canadian_french">Canadian French (Français canadien)</string>
<string name="language_latin_american_spanish">Latin American Spanish (Español latinoamericano)</string>
<string name="language_simplified_chinese">Simplified Chinese (简体中文)</string>
<string name="language_traditional_chinese">Traditional Chinese (正體中文)</string>
<string name="language_brazilian_portuguese">Brazilian Portuguese (Português do Brasil)</string>
<!-- Memory Sizes -->
<string name="memory_byte">Byte</string>

View File

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

View File

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

View File

@@ -51,7 +51,7 @@ struct PageTable {
class PageInfo {
public:
/// Returns the page pointer
[[nodiscard]] uintptr_t Pointer() const noexcept {
[[nodiscard]] u8* Pointer() const noexcept {
return ExtractPointer(raw.load(std::memory_order_relaxed));
}
@@ -61,7 +61,7 @@ struct PageTable {
}
/// Returns the page pointer and attribute pair, extracted from the same atomic read
[[nodiscard]] std::pair<uintptr_t, PageType> PointerType() const noexcept {
[[nodiscard]] std::pair<u8*, PageType> PointerType() const noexcept {
const uintptr_t non_atomic_raw = raw.load(std::memory_order_relaxed);
return {ExtractPointer(non_atomic_raw), ExtractType(non_atomic_raw)};
}
@@ -73,13 +73,13 @@ struct PageTable {
}
/// Write a page pointer and type pair atomically
void Store(uintptr_t pointer, PageType type) noexcept {
raw.store(pointer | static_cast<uintptr_t>(type));
void Store(u8* pointer, PageType type) noexcept {
raw.store(reinterpret_cast<uintptr_t>(pointer) | static_cast<uintptr_t>(type));
}
/// Unpack a pointer from a page info raw representation
[[nodiscard]] static uintptr_t ExtractPointer(uintptr_t raw) noexcept {
return raw & (~uintptr_t{0} << ATTRIBUTE_BITS);
[[nodiscard]] static u8* ExtractPointer(uintptr_t raw) noexcept {
return reinterpret_cast<u8*>(raw & (~uintptr_t{0} << ATTRIBUTE_BITS));
}
/// Unpack a page type from a page info raw representation

View File

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

View File

@@ -4,13 +4,13 @@
#include <chrono>
#include <exception>
#include <iomanip>
#include <map>
#include <sstream>
#include <stdexcept>
#include <fmt/chrono.h>
#include <fmt/core.h>
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/time_zone.h"
namespace Common::TimeZone {
@@ -33,29 +33,32 @@ std::string GetDefaultTimeZone() {
return "GMT";
}
// Results are not comparable to seconds since Epoch
static std::time_t TmSpecToSeconds(const struct std::tm& spec) {
const int year = spec.tm_year - 1; // Years up to now
const int leap_years = year / 4 - year / 100;
std::time_t cumulative = spec.tm_year;
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
cumulative = cumulative * 60 + spec.tm_sec; // Minutes to seconds
return cumulative;
static std::string GetOsTimeZoneOffset() {
const std::time_t t{std::time(nullptr)};
const std::tm tm{*std::localtime(&t)};
return fmt::format("{:%z}", tm);
}
static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) {
try {
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() {
const std::time_t t{std::time(nullptr)};
const std::tm local{*std::localtime(&t)};
const std::tm gmt{*std::gmtime(&t)};
const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())};
// gmt_seconds is a different offset than time(nullptr)
const auto gmt_seconds = TmSpecToSeconds(gmt);
const auto local_seconds = TmSpecToSeconds(local);
const auto seconds_offset = local_seconds - gmt_seconds;
int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds
seconds += (offset % 100) * 60; // Convert minute component to seconds
return std::chrono::seconds{seconds_offset};
return std::chrono::seconds{seconds};
}
// 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() {
#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 minutes = seconds / 60;
@@ -89,6 +97,7 @@ std::string FindSystemTimeZone() {
}
}
return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours));
#endif
}
} // namespace Common::TimeZone

View File

@@ -217,8 +217,8 @@ void ARM_Interface::Run() {
}
}
void ARM_Interface::LoadWatchpointArray(const WatchpointArray* wp) {
watchpoints = wp;
void ARM_Interface::LoadWatchpointArray(const WatchpointArray& wp) {
watchpoints = &wp;
}
const Kernel::DebugWatchpoint* ARM_Interface::MatchingWatchpoint(

View File

@@ -186,7 +186,7 @@ public:
virtual void SaveContext(ThreadContext64& ctx) const = 0;
virtual void LoadContext(const ThreadContext32& ctx) = 0;
virtual void LoadContext(const ThreadContext64& ctx) = 0;
void LoadWatchpointArray(const WatchpointArray* wp);
void LoadWatchpointArray(const WatchpointArray& wp);
/// Clears the exclusive monitor's state.
virtual void ClearExclusiveState() = 0;

View File

@@ -346,11 +346,11 @@ void ARM_Dynarmic_32::RewindBreakpointInstruction() {
}
ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_,
DynarmicExclusiveMonitor& exclusive_monitor_,
std::size_t core_index_)
ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_)
: ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)),
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;

View File

@@ -12,7 +12,7 @@
#include "common/common_types.h"
#include "common/hash.h"
#include "core/arm/arm_interface.h"
#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h"
#include "core/arm/exclusive_monitor.h"
namespace Core::Memory {
class Memory;
@@ -28,8 +28,8 @@ class System;
class ARM_Dynarmic_32 final : public ARM_Interface {
public:
ARM_Dynarmic_32(System& system_, bool uses_wall_clock_,
DynarmicExclusiveMonitor& exclusive_monitor_, std::size_t core_index_);
ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_,
std::size_t core_index_);
~ARM_Dynarmic_32() 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_,
DynarmicExclusiveMonitor& exclusive_monitor_,
std::size_t core_index_)
ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_)
: ARM_Interface{system_, uses_wall_clock_},
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;

View File

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

View File

@@ -6,6 +6,8 @@
#include <dynarmic/interface/exclusive_monitor.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"
namespace Core::Memory {
@@ -14,9 +16,6 @@ class Memory;
namespace Core {
class ARM_Dynarmic_32;
class ARM_Dynarmic_64;
class DynarmicExclusiveMonitor final : public ExclusiveMonitor {
public:
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;
}
FileSys::ContentProviderUnion& System::GetContentProviderUnion() {
return *impl->content_provider;
}
const FileSys::ContentProviderUnion& System::GetContentProviderUnion() const {
return *impl->content_provider;
}
Service::FileSystem::FileSystemController& System::GetFileSystemController() {
return impl->fs_controller;
}

View File

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

View File

@@ -261,8 +261,10 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))};
const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))};
std::vector<u8> mem(size);
if (system.ApplicationMemory().ReadBlock(addr, mem.data(), size)) {
if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
std::vector<u8> mem(size);
system.ApplicationMemory().ReadBlock(addr, mem.data(), size);
SendReply(Common::HexToString(mem));
} else {
SendReply(GDB_STUB_REPLY_ERR);
@@ -279,7 +281,8 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
const auto mem_substr{std::string_view(command).substr(mem_sep)};
const auto mem{Common::HexStringToVector(mem_substr, false)};
if (system.ApplicationMemory().WriteBlock(addr, mem.data(), size)) {
if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) {
system.ApplicationMemory().WriteBlock(addr, mem.data(), size);
system.InvalidateCpuInstructionCacheRange(addr, size);
SendReply(GDB_STUB_REPLY_OK);
} else {
@@ -553,7 +556,7 @@ void GDBStub::HandleQuery(std::string_view command) {
} else {
SendReply(fmt::format(
"TextSeg={:x}",
GetInteger(system.ApplicationProcess()->GetPageTable().GetCodeRegionStart())));
GetInteger(system.ApplicationProcess()->PageTable().GetCodeRegionStart())));
}
} else if (command.starts_with("Xfer:libraries:read::")) {
Loader::AppLoader::Modules modules;
@@ -728,7 +731,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
std::string reply;
auto* process = system.ApplicationProcess();
auto& page_table = process->GetPageTable();
auto& page_table = process->PageTable();
const char* commands = "Commands:\n"
" get fastmem\n"

View File

@@ -15,8 +15,8 @@ void KAutoObject::RegisterWithKernel() {
m_kernel.RegisterKernelObject(this);
}
void KAutoObject::UnregisterWithKernel(KernelCore& kernel, KAutoObject* self) {
kernel.UnregisterKernelObject(self);
void KAutoObject::UnregisterWithKernel() {
m_kernel.UnregisterKernelObject(this);
}
} // namespace Kernel

View File

@@ -159,15 +159,14 @@ public:
// If ref count hits zero, destroy the object.
if (cur_ref_count - 1 == 0) {
KernelCore& kernel = m_kernel;
this->Destroy();
KAutoObject::UnregisterWithKernel(kernel, this);
this->UnregisterWithKernel();
}
}
private:
void RegisterWithKernel();
static void UnregisterWithKernel(KernelCore& kernel, KAutoObject* self);
void UnregisterWithKernel();
protected:
KernelCore& m_kernel;

View File

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

View File

@@ -388,6 +388,39 @@ public:
constexpr size_t GetHeapSize() const {
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 {
return IsKernel() ? 1 : 4;
}
@@ -403,14 +436,6 @@ public:
return m_address_space_start <= addr && addr < addr + size &&
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:
static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout,

View File

@@ -38,7 +38,7 @@ namespace {
*/
void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
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));
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,
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.
KPageTable& GetPageTable() {
return m_page_table;

View File

@@ -510,12 +510,11 @@ void KScheduler::Unload(KThread* thread) {
void KScheduler::Reload(KThread* thread) {
auto& cpu_core = m_kernel.System().ArmInterface(m_core_id);
auto* process = thread->GetOwnerProcess();
cpu_core.LoadContext(thread->GetContext32());
cpu_core.LoadContext(thread->GetContext64());
cpu_core.SetTlsAddress(GetInteger(thread->GetTlsAddress()));
cpu_core.SetTPIDR_EL0(thread->GetTpidrEl0());
cpu_core.LoadWatchpointArray(process ? &process->GetWatchpoints() : nullptr);
cpu_core.LoadWatchpointArray(thread->GetOwnerProcess()->GetWatchpoints());
cpu_core.ClearExclusiveState();
}

View File

@@ -90,8 +90,8 @@ Result KSharedMemory::Map(KProcess& target_process, KProcessAddress address, std
R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission);
}
R_RETURN(target_process.GetPageTable().MapPageGroup(
address, *m_page_group, KMemoryState::Shared, ConvertToKMemoryPermission(map_perm)));
R_RETURN(target_process.PageTable().MapPageGroup(address, *m_page_group, KMemoryState::Shared,
ConvertToKMemoryPermission(map_perm)));
}
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_RETURN(
target_process.GetPageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::Shared));
target_process.PageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::Shared));
}
} // namespace Kernel

View File

@@ -129,7 +129,7 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress
case ThreadType::User:
ASSERT(((owner == nullptr) ||
(owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask()));
ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) ||
ASSERT(((owner == nullptr) ||
(owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask()));
break;
case ThreadType::Kernel:
@@ -302,12 +302,12 @@ Result KThread::InitializeServiceThread(Core::System& system, KThread* thread,
std::function<void()>&& func, s32 prio, s32 virt_core,
KProcess* owner) {
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.
system.Kernel().CurrentScheduler()->OnThreadStart();
// Run the guest function.
func_();
func();
// Exit.
Svc::ExitThread(system);

View File

@@ -25,9 +25,9 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
// Map the address in.
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,
KMemoryState::ThreadLocal,
KMemoryPermission::UserReadWrite));
R_TRY(m_owner->PageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, phys_addr,
KMemoryState::ThreadLocal,
KMemoryPermission::UserReadWrite));
// We succeeded.
page_buf_guard.Cancel();
@@ -37,11 +37,11 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
Result KThreadLocalPage::Finalize() {
// 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);
// 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.
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);
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.
Common::SetCurrentThreadName(thread_name_.c_str());
Common::SetCurrentThreadName(thread_name.c_str());
// Set the thread as current.
kernel.RegisterHostThread(thread);
// Run the callback.
func_();
func();
// Close the thread.
// 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.
auto& kernel = system.Kernel();
m_arm_interface = std::make_unique<Core::ARM_Dynarmic_64>(
system, kernel.IsMulticore(),
reinterpret_cast<Core::DynarmicExclusiveMonitor&>(kernel.GetExclusiveMonitor()),
m_core_index);
system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), m_core_index);
#else
#error Platform not supported yet.
#endif
@@ -33,9 +31,7 @@ void PhysicalCore::Initialize(bool is_64_bit) {
if (!is_64_bit) {
// We already initialized a 64-bit core, replace with a 32-bit one.
m_arm_interface = std::make_unique<Core::ARM_Dynarmic_32>(
m_system, kernel.IsMulticore(),
reinterpret_cast<Core::DynarmicExclusiveMonitor&>(kernel.GetExclusiveMonitor()),
m_core_index);
m_system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), m_core_index);
}
#else
#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);
// Verify the region is within range.
auto& page_table = process->GetPageTable();
auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// 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(); });
// 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);
// Initialize the code memory.
@@ -92,7 +92,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
case CodeMemoryOperation::Map: {
// Check that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel())
.GetPageTable()
.PageTable()
.CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion);
@@ -105,7 +105,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
case CodeMemoryOperation::Unmap: {
// Check that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel())
.GetPageTable()
.PageTable()
.CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion);
@@ -117,8 +117,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
} break;
case CodeMemoryOperation::MapToOwner: {
// Check that the region is in range.
R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size,
KMemoryState::GeneratedCode),
R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size,
KMemoryState::GeneratedCode),
ResultInvalidMemoryRegion);
// Check the memory permission.
@@ -129,8 +129,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
} break;
case CodeMemoryOperation::UnmapFromOwner: {
// Check that the region is in range.
R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size,
KMemoryState::GeneratedCode),
R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size,
KMemoryState::GeneratedCode),
ResultInvalidMemoryRegion);
// Check the memory permission.

View File

@@ -107,7 +107,7 @@ Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Han
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// 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);
// Map.
@@ -148,7 +148,7 @@ Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Han
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// 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);
// Map.
@@ -180,7 +180,7 @@ Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle p
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// 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_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();
case InfoType::AliasRegionAddress:
*result = GetInteger(process->GetPageTable().GetAliasRegionStart());
*result = GetInteger(process->PageTable().GetAliasRegionStart());
R_SUCCEED();
case InfoType::AliasRegionSize:
*result = process->GetPageTable().GetAliasRegionSize();
*result = process->PageTable().GetAliasRegionSize();
R_SUCCEED();
case InfoType::HeapRegionAddress:
*result = GetInteger(process->GetPageTable().GetHeapRegionStart());
*result = GetInteger(process->PageTable().GetHeapRegionStart());
R_SUCCEED();
case InfoType::HeapRegionSize:
*result = process->GetPageTable().GetHeapRegionSize();
*result = process->PageTable().GetHeapRegionSize();
R_SUCCEED();
case InfoType::AslrRegionAddress:
*result = GetInteger(process->GetPageTable().GetAliasCodeRegionStart());
*result = GetInteger(process->PageTable().GetAliasCodeRegionStart());
R_SUCCEED();
case InfoType::AslrRegionSize:
*result = process->GetPageTable().GetAliasCodeRegionSize();
*result = process->PageTable().GetAliasCodeRegionSize();
R_SUCCEED();
case InfoType::StackRegionAddress:
*result = GetInteger(process->GetPageTable().GetStackRegionStart());
*result = GetInteger(process->PageTable().GetStackRegionStart());
R_SUCCEED();
case InfoType::StackRegionSize:
*result = process->GetPageTable().GetStackRegionSize();
*result = process->PageTable().GetStackRegionSize();
R_SUCCEED();
case InfoType::TotalMemorySize:

View File

@@ -8,7 +8,6 @@
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
@@ -50,11 +49,15 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
// Copy user handles.
if (num_handles > 0) {
// Get the handles.
R_UNLESS(GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(),
sizeof(Handle) * num_handles),
// Ensure we can try to get the handles.
R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
ResultInvalidPointer);
// Get the handles.
GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(),
sizeof(Handle) * num_handles);
// Convert the handles to objects.
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
objs.data(), handles.data(), num_handles),

View File

@@ -63,13 +63,36 @@ Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 s
R_THROW(ResultInvalidCurrentMemory);
}
if (!manager.Contains(src_addr, size)) {
if (!manager.IsInsideAddressSpace(src_addr, size)) {
LOG_ERROR(Kernel_SVC,
"Source is not within the address space, addr=0x{:016X}, size=0x{:016X}",
src_addr, size);
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();
}
@@ -89,7 +112,7 @@ Result SetMemoryPermission(Core::System& system, u64 address, u64 size, MemoryPe
R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission);
// 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);
// 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);
// 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);
// 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,
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)};
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,
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)};
result.IsError()) {

View File

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

View File

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

View File

@@ -49,7 +49,7 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, u
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// 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);
// 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);
// Get the page tables.
auto& dst_pt = dst_process->GetPageTable();
auto& src_pt = src_process->GetPageTable();
auto& dst_pt = dst_process->PageTable();
auto& src_pt = src_process->PageTable();
// Validate that the mapping is in range.
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);
// Get the page tables.
auto& dst_pt = dst_process->GetPageTable();
auto& src_pt = src_process->GetPageTable();
auto& dst_pt = dst_process->PageTable();
auto& src_pt = src_process->PageTable();
// Validate that the mapping is in range.
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);
}
auto& page_table = process->GetPageTable();
if (!page_table.Contains(src_address, size)) {
auto& page_table = process->PageTable();
if (!page_table.IsInsideAddressSpace(src_address, size)) {
LOG_ERROR(Kernel_SVC,
"Source address range is not within the address space (src_address=0x{:016X}, "
"size=0x{:016X}).",
@@ -187,6 +187,14 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
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));
}
@@ -238,8 +246,8 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
R_THROW(ResultInvalidHandle);
}
auto& page_table = process->GetPageTable();
if (!page_table.Contains(src_address, size)) {
auto& page_table = process->PageTable();
if (!page_table.IsInsideAddressSpace(src_address, size)) {
LOG_ERROR(Kernel_SVC,
"Source address range is not within the address space (src_address=0x{:016X}, "
"size=0x{:016X}).",
@@ -247,6 +255,14 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
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,
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())};
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));

View File

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

View File

@@ -7,7 +7,6 @@
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
@@ -65,11 +64,15 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
// Copy user handles.
if (num_handles > 0) {
// Get the handles.
R_UNLESS(GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(),
sizeof(Handle) * num_handles),
// Ensure we can try to get the handles.
R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
user_handles, static_cast<u64>(sizeof(Handle) * num_handles)),
ResultInvalidPointer);
// Get the handles.
GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(),
sizeof(Handle) * num_handles);
// Convert the handles to objects.
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
objs.data(), handles.data(), num_handles),

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);
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}",
out_thread_ids, out_thread_ids + total_copy_size);
R_THROW(ResultInvalidCurrentMemory);

View File

@@ -55,7 +55,7 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64
SCOPE_EXIT({ trmem->Close(); });
// 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.
R_TRY(trmem->Initialize(address, size, map_perm));

View File

@@ -496,9 +496,8 @@ public:
void LoadIdTokenCache(HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(0);
}
protected:

View File

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

View File

@@ -2,48 +2,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/glue/ectx.h"
#include "core/hle/service/ipc_helpers.h"
namespace Service::Glue {
// This is nn::err::context::IContextRegistrar
class IContextRegistrar : public ServiceFramework<IContextRegistrar> {
public:
IContextRegistrar(Core::System& system_) : ServiceFramework{system_, "IContextRegistrar"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IContextRegistrar::Complete, "Complete"},
};
// clang-format on
RegisterHandlers(functions);
}
~IContextRegistrar() override = default;
private:
void Complete(HLERequestContext& ctx) {
struct InputParameters {
u32 unk;
};
struct OutputParameters {
u32 unk;
};
IPC::RequestParser rp{ctx};
[[maybe_unused]] auto input = rp.PopRaw<InputParameters>();
[[maybe_unused]] auto value = ctx.ReadBuffer();
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(0);
}
};
ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ECTX_AW::CreateContextRegistrar, "CreateContextRegistrar"},
{0, nullptr, "CreateContextRegistrar"},
{1, nullptr, "CommitContext"},
};
// clang-format on
@@ -53,10 +18,4 @@ ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
ECTX_AW::~ECTX_AW() = default;
void ECTX_AW::CreateContextRegistrar(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IContextRegistrar>(std::make_shared<IContextRegistrar>(system));
}
} // namespace Service::Glue

View File

@@ -15,9 +15,6 @@ class ECTX_AW final : public ServiceFramework<ECTX_AW> {
public:
explicit ECTX_AW(Core::System& system_);
~ECTX_AW() override;
private:
void CreateContextRegistrar(HLERequestContext& ctx);
};
} // namespace Service::Glue

View File

@@ -318,15 +318,15 @@ public:
return false;
}
if (!page_table.Contains(out_addr, size)) {
if (!page_table.IsInsideAddressSpace(out_addr, size)) {
return false;
}
if (page_table.IsInHeapRegion(out_addr, size)) {
if (page_table.IsInsideHeapRegion(out_addr, size)) {
return false;
}
if (page_table.IsInAliasRegion(out_addr, size)) {
if (page_table.IsInsideAliasRegion(out_addr, size)) {
return false;
}
@@ -358,7 +358,7 @@ public:
}
ResultVal<VAddr> MapProcessCodeMemory(Kernel::KProcess* process, VAddr base_addr, u64 size) {
auto& page_table{process->GetPageTable()};
auto& page_table{process->PageTable()};
VAddr addr{};
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,
VAddr bss_addr, std::size_t bss_size, std::size_t size) {
for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) {
auto& page_table{process->GetPageTable()};
auto& page_table{process->PageTable()};
VAddr addr{};
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,
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));
CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission(
CASCADE_CODE(process->PageTable().SetProcessMemoryPermission(
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);
}
@@ -571,7 +571,7 @@ public:
Result UnmapNro(const NROInfo& info) {
// 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) {
CASCADE_CODE(page_table.UnmapCodeMemory(
@@ -643,7 +643,7 @@ public:
initialized = true;
current_map_addr =
GetInteger(system.ApplicationProcess()->GetPageTable().GetAliasCodeRegionStart());
GetInteger(system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart());
IPC::ResponseBuilder rb{ctx, 2};
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,
std::span<const u8> seed) {
const std::vector<u8>& seed) {
// Initialize context
ctx.used = false;
ctx.counter = 0;

View File

@@ -75,7 +75,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
// Initializes mbedtls context
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
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/nfc_result.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 {
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 {
// TODO: This should get the npad id from nn::hid::system::GetXcdHandleForNpadWithNfc
out_npad_id = npad_id;
return ResultSuccess;
}

View File

@@ -1,8 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <algorithm>
#include "common/logging/log.h"
#include "core/core.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/nfc_result.h"
#include "core/hle/service/time/clock_types.h"
#include "core/hle/service/time/time_manager.h"
namespace Service::NFC {
@@ -54,53 +51,22 @@ Result DeviceManager::Finalize() {
return ResultSuccess;
}
Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices,
bool skip_fatal_errors) 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;
}
Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices,
std::size_t max_allowed_devices) const {
for (auto& device : devices) {
if (nfp_devices.size() >= max_allowed_devices) {
continue;
}
if (skip_fatal_errors) {
constexpr u64 MinimumRecoveryTime = 60;
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) {
nfp_devices.push_back(device->GetHandle());
}
if (device->GetCurrentState() == DeviceState::Unavailable) {
continue;
}
nfp_devices.push_back(device->GetHandle());
}
if (nfp_devices.empty()) {
return ResultDeviceNotFound;
}
return result;
return ResultSuccess;
}
DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
@@ -113,10 +79,10 @@ DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
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::shared_ptr<NfcDevice> device = nullptr;
@@ -162,7 +128,7 @@ Result DeviceManager::StopDetection(u64 device_handle) {
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::shared_ptr<NfcDevice> device = nullptr;
@@ -176,46 +142,24 @@ Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) {
return result;
}
Result DeviceManager::AttachActivateEvent(Kernel::KReadableEvent** out_event,
u64 device_handle) const {
std::vector<u64> nfp_devices;
Kernel::KReadableEvent& DeviceManager::AttachActivateEvent(u64 device_handle) const {
std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr;
Result result = ListDevices(nfp_devices, 9, false);
GetDeviceFromHandle(device_handle, device, false);
if (result.IsSuccess()) {
result = CheckHandleOnList(device_handle, nfp_devices);
}
if (result.IsSuccess()) {
result = GetDeviceFromHandle(device_handle, device, false);
}
if (result.IsSuccess()) {
*out_event = &device->GetActivateEvent();
}
return result;
// TODO: Return proper error code on failure
return device->GetActivateEvent();
}
Result DeviceManager::AttachDeactivateEvent(Kernel::KReadableEvent** out_event,
u64 device_handle) const {
std::vector<u64> nfp_devices;
Kernel::KReadableEvent& DeviceManager::AttachDeactivateEvent(u64 device_handle) const {
std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr;
Result result = ListDevices(nfp_devices, 9, false);
GetDeviceFromHandle(device_handle, device, false);
if (result.IsSuccess()) {
result = CheckHandleOnList(device_handle, nfp_devices);
}
if (result.IsSuccess()) {
result = GetDeviceFromHandle(device_handle, device, false);
}
if (result.IsSuccess()) {
*out_event = &device->GetDeactivateEvent();
}
return result;
// TODO: Return proper error code on failure
return device->GetDeactivateEvent();
}
Result DeviceManager::ReadMifare(u64 device_handle,
@@ -309,7 +253,7 @@ Result DeviceManager::OpenApplicationArea(u64 device_handle, u32 access_id) {
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::shared_ptr<NfcDevice> device = nullptr;
@@ -380,7 +324,7 @@ Result DeviceManager::CreateApplicationArea(u64 device_handle, u32 access_id,
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::shared_ptr<NfcDevice> device = nullptr;
@@ -394,7 +338,7 @@ Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& regi
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::shared_ptr<NfcDevice> device = nullptr;
@@ -408,7 +352,7 @@ Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_i
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::shared_ptr<NfcDevice> device = nullptr;
@@ -455,7 +399,7 @@ Result DeviceManager::Format(u64 device_handle) {
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::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,
NFP::RegisterInfoPrivate& register_info) {
NFP::RegisterInfoPrivate& register_info) const {
std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr;
@@ -527,7 +471,7 @@ Result DeviceManager::DeleteApplicationArea(u64 device_handle) {
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::shared_ptr<NfcDevice> device = nullptr;
@@ -541,7 +485,7 @@ Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_applica
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::shared_ptr<NfcDevice> device = nullptr;
@@ -597,7 +541,7 @@ Result DeviceManager::BreakTag(u64 device_handle, NFP::BreakType break_type) {
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::shared_ptr<NfcDevice> device = nullptr;
@@ -649,19 +593,6 @@ Result DeviceManager::WriteNtf(u64 device_handle, NFP::WriteType, std::span<cons
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,
bool check_state) const {
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 operation_result) {
Result operation_result) const {
if (operation_result.IsSuccess()) {
return operation_result;
}
@@ -738,12 +669,6 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
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;
}

View File

@@ -27,16 +27,15 @@ public:
// Nfc device manager
Result Initialize();
Result Finalize();
Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices,
bool skip_fatal_errors) const;
Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices) 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;
Result StartDetection(u64 device_handle, NfcProtocol tag_protocol);
Result StopDetection(u64 device_handle);
Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info);
Result AttachActivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const;
Result AttachDeactivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const;
Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info) const;
Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const;
Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const;
Result ReadMifare(u64 device_handle,
const std::span<const MifareReadBlockParameter> read_parameters,
std::span<MifareReadBlockData> read_data);
@@ -49,28 +48,28 @@ public:
Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target);
Result Unmount(u64 device_handle);
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 Flush(u64 device_handle);
Result Restore(u64 device_handle);
Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info);
Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info);
Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info);
Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const;
Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const;
Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const;
u32 GetApplicationAreaSize() const;
Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
Result Format(u64 device_handle);
Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info);
Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info);
Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const;
Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info) const;
Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info);
Result DeleteRegisterInfo(u64 device_handle);
Result DeleteApplicationArea(u64 device_handle);
Result ExistsApplicationArea(u64 device_handle, bool& has_application_area);
Result GetAll(u64 device_handle, NFP::NfpData& nfp_data);
Result ExistsApplicationArea(u64 device_handle, bool& has_application_area) const;
Result GetAll(u64 device_handle, NFP::NfpData& nfp_data) const;
Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data);
Result FlushDebug(u64 device_handle);
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 WriteNtf(u64 device_handle, NFP::WriteType, std::span<const u8> data);
@@ -79,20 +78,17 @@ private:
Result IsNfcParameterSet() 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,
bool check_state) 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;
std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle);
const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const;
bool is_initialized = false;
u64 time_since_last_error = 0;
mutable std::mutex mutex;
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>();
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);
if (result.IsError()) {
@@ -190,13 +190,9 @@ void NfcInterface::AttachActivateEvent(HLERequestContext& ctx) {
const auto device_handle{rp.Pop<u64>()};
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};
rb.Push(result);
rb.PushCopyObjects(out_event);
rb.Push(ResultSuccess);
rb.PushCopyObjects(GetManager()->AttachActivateEvent(device_handle));
}
void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
@@ -204,13 +200,9 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
const auto device_handle{rp.Pop<u64>()};
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};
rb.Push(result);
rb.PushCopyObjects(out_event);
rb.Push(ResultSuccess);
rb.PushCopyObjects(GetManager()->AttachDeactivateEvent(device_handle));
}
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 ResultWriteAmiiboFailed(ErrorModule::NFC, 88);
constexpr Result ResultTagRemoved(ErrorModule::NFC, 97);
constexpr Result ResultUnknown112(ErrorModule::NFC, 112);
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 ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128);
constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136);

View File

@@ -128,7 +128,7 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) {
}
bool is_out_io{};
ASSERT(system.ApplicationProcess()
->GetPageTable()
->PageTable()
.LockForMapDeviceAddressSpace(&is_out_io, handle_description->address,
handle_description->size,
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 (freeInfo->can_unlock) {
ASSERT(system.ApplicationProcess()
->GetPageTable()
->PageTable()
.UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size)
.IsSuccess());
}

View File

@@ -559,7 +559,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con
const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd];
if (!descriptor) {
LOG_TRACE(Service, "File descriptor handle={} is not allocated", pollfd.fd);
LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd);
pollfd.revents = PollEvents::Nval;
return {0, Errno::SUCCESS};
}

View File

@@ -10,21 +10,12 @@ namespace Service::Sockets {
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} {
// clang-format off
static const FunctionInfo functions[] = {
{5, nullptr, "GetSettingUrl"},
{10, nullptr, "GetSettingName"},
{11, &NSD::GetEnvironmentIdentifier, "GetEnvironmentIdentifier"},
{11, nullptr, "GetEnvironmentIdentifier"},
{12, nullptr, "GetDeviceId"},
{13, nullptr, "DeleteSettings"},
{14, nullptr, "ImportSettings"},
@@ -45,7 +36,7 @@ NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
{62, nullptr, "DeleteSaveDataOfFsForTest"},
{63, nullptr, "IsChangeEnvironmentIdentifierDisabled"},
{64, nullptr, "SetWithoutDomainExchangeFqdns"},
{100, &NSD::GetApplicationServerEnvironmentType, "GetApplicationServerEnvironmentType"},
{100, nullptr, "GetApplicationServerEnvironmentType"},
{101, nullptr, "SetApplicationServerEnvironmentType"},
{102, nullptr, "DeleteApplicationServerEnvironmentType"},
};
@@ -103,20 +94,6 @@ void NSD::ResolveEx(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) {
const std::string environment_identifier = "lp1";
ctx.WriteBuffer(environment_identifier);
IPC::ResponseBuilder rb{ctx, 2};
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;
} // namespace Service::Sockets

View File

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

View File

@@ -24,7 +24,7 @@ SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"
{2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"},
{3, nullptr, "GetHostByAddrRequest"},
{4, nullptr, "GetHostStringErrorRequest"},
{5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"},
{5, nullptr, "GetGaiStringErrorRequest"},
{6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"},
{7, nullptr, "GetNameInfoRequest"},
{8, nullptr, "RequestCancelHandleRequest"},
@@ -300,20 +300,6 @@ void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) {
});
}
void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) {
struct InputParameters {
GetAddrInfoError gai_errno;
};
IPC::RequestParser rp{ctx};
auto input = rp.PopRaw<InputParameters>();
const std::string result = Translate(input.gai_errno);
ctx.WriteBuffer(result);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) {
// Additional options are ignored
auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx);

View File

@@ -18,7 +18,6 @@ public:
private:
void GetHostByNameRequest(HLERequestContext& ctx);
void GetGaiStringErrorRequest(HLERequestContext& ctx);
void GetHostByNameRequestWithOptions(HLERequestContext& ctx);
void GetAddrInfoRequest(HLERequestContext& ctx);
void GetAddrInfoRequestWithOptions(HLERequestContext& ctx);

View File

@@ -81,44 +81,6 @@ GetAddrInfoError Translate(Network::GetAddrInfoError error) {
}
}
const char* Translate(GetAddrInfoError error) {
// https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254
switch (error) {
case GetAddrInfoError::SUCCESS:
return "Success";
case GetAddrInfoError::ADDRFAMILY:
return "Address family for hostname not supported";
case GetAddrInfoError::AGAIN:
return "Temporary failure in name resolution";
case GetAddrInfoError::BADFLAGS:
return "Invalid value for ai_flags";
case GetAddrInfoError::FAIL:
return "Non-recoverable failure in name resolution";
case GetAddrInfoError::FAMILY:
return "ai_family not supported";
case GetAddrInfoError::MEMORY:
return "Memory allocation failure";
case GetAddrInfoError::NODATA:
return "No address associated with hostname";
case GetAddrInfoError::NONAME:
return "hostname nor servname provided, or not known";
case GetAddrInfoError::SERVICE:
return "servname not supported for ai_socktype";
case GetAddrInfoError::SOCKTYPE:
return "ai_socktype not supported";
case GetAddrInfoError::SYSTEM:
return "System error returned in errno";
case GetAddrInfoError::BADHINTS:
return "Invalid value for hints";
case GetAddrInfoError::PROTOCOL:
return "Resolved protocol is unknown";
case GetAddrInfoError::OVERFLOW_:
return "Argument buffer overflow";
default:
return "Unknown error";
}
}
Network::Domain Translate(Domain domain) {
switch (domain) {
case Domain::Unspecified:

View File

@@ -20,9 +20,6 @@ std::pair<s32, Errno> Translate(std::pair<s32, Network::Errno> value);
/// Translate abstract getaddrinfo error to guest getaddrinfo error
GetAddrInfoError Translate(Network::GetAddrInfoError value);
/// Translate guest error to string
const char* Translate(GetAddrInfoError value);
/// Translate guest domain to abstract domain
Network::Domain Translate(Domain domain);

View File

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

View File

@@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
}
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);
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
codeset.memory = std::move(program_image);
process.LoadModule(std::move(codeset), process.GetPageTable().GetCodeRegionStart());
process.LoadModule(std::move(codeset), process.PageTable().GetCodeRegionStart());
return true;
}

View File

@@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
modules.clear();
// 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)) {
return {ResultStatus::ErrorLoadingNSO, {}};
}

View File

@@ -24,16 +24,6 @@
namespace Core::Memory {
namespace {
bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessAddress addr,
const std::size_t size) {
const Common::ProcessAddress max_addr = 1ULL << table.GetAddressSpaceBits();
return addr + size >= addr && addr + size <= max_addr;
}
} // namespace
// Implementation class used to keep the specifics of the memory subsystem hidden
// from outside classes. This also allows modification to the internals of the memory
// subsystem without needing to rebuild all files that make use of the memory interface.
@@ -41,10 +31,10 @@ struct Memory::Impl {
explicit Impl(Core::System& system_) : system{system_} {}
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();
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);
}
@@ -83,7 +73,7 @@ struct Memory::Impl {
return {};
}
return system.DeviceMemory().GetPointer<u8>(paddr + vaddr);
return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr;
}
[[nodiscard]] u8* GetPointerFromDebugMemory(u64 vaddr) const {
@@ -94,7 +84,7 @@ struct Memory::Impl {
return {};
}
return system.DeviceMemory().GetPointer<u8>(paddr + vaddr);
return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr;
}
u8 Read8(const Common::ProcessAddress addr) {
@@ -193,18 +183,13 @@ struct Memory::Impl {
return string;
}
bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
auto on_memory, auto on_rasterizer, auto increment) {
const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl();
void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr,
const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer,
auto increment) {
const auto& page_table = process.PageTable().PageTableImpl();
std::size_t remaining_size = size;
std::size_t page_index = addr >> YUZU_PAGEBITS;
std::size_t page_offset = addr & YUZU_PAGEMASK;
bool user_accessible = true;
if (!AddressSpaceContains(page_table, addr, size)) [[unlikely]] {
on_unmapped(size, addr);
return false;
}
while (remaining_size) {
const std::size_t copy_amount =
@@ -215,13 +200,11 @@ struct Memory::Impl {
const auto [pointer, type] = page_table.pointers[page_index].PointerType();
switch (type) {
case Common::PageType::Unmapped: {
user_accessible = false;
on_unmapped(copy_amount, current_vaddr);
break;
}
case Common::PageType::Memory: {
u8* mem_ptr =
reinterpret_cast<u8*>(pointer + page_offset + (page_index << YUZU_PAGEBITS));
u8* mem_ptr = pointer + page_offset + (page_index << YUZU_PAGEBITS);
on_memory(copy_amount, mem_ptr);
break;
}
@@ -244,15 +227,13 @@ struct Memory::Impl {
increment(copy_amount);
remaining_size -= copy_amount;
}
return user_accessible;
}
template <bool UNSAFE>
bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) {
return WalkBlock(
src_addr, size,
void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr,
void* dest_buffer, const std::size_t size) {
WalkBlock(
process, src_addr, size,
[src_addr, size, &dest_buffer](const std::size_t copy_amount,
const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory,
@@ -275,14 +256,14 @@ struct Memory::Impl {
});
}
bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) {
return ReadBlockImpl<false>(src_addr, dest_buffer, size);
ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
}
bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) {
return ReadBlockImpl<true>(src_addr, dest_buffer, size);
ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
}
const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
@@ -302,10 +283,10 @@ struct Memory::Impl {
}
template <bool UNSAFE>
bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) {
return WalkBlock(
dest_addr, size,
void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
const void* src_buffer, const std::size_t size) {
WalkBlock(
process, dest_addr, size,
[dest_addr, size](const std::size_t copy_amount,
const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory,
@@ -327,19 +308,20 @@ struct Memory::Impl {
});
}
bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) {
return WriteBlockImpl<false>(dest_addr, src_buffer, size);
WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
}
bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) {
return WriteBlockImpl<true>(dest_addr, src_buffer, size);
WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
}
bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) {
return WalkBlock(
dest_addr, size,
void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
const std::size_t size) {
WalkBlock(
process, dest_addr, size,
[dest_addr, size](const std::size_t copy_amount,
const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory,
@@ -357,23 +339,23 @@ struct Memory::Impl {
[](const std::size_t copy_amount) {});
}
bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
const std::size_t size) {
return WalkBlock(
dest_addr, size,
void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
Common::ProcessAddress src_addr, const std::size_t size) {
WalkBlock(
process, dest_addr, size,
[&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory,
"Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
GetInteger(current_vaddr), GetInteger(src_addr), size);
ZeroBlock(dest_addr, copy_amount);
ZeroBlock(process, dest_addr, copy_amount);
},
[&](const std::size_t copy_amount, const u8* const src_ptr) {
WriteBlockImpl<false>(dest_addr, src_ptr, copy_amount);
WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount);
},
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) {
HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
WriteBlockImpl<false>(dest_addr, host_ptr, copy_amount);
WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount);
},
[&](const std::size_t copy_amount) {
dest_addr += copy_amount;
@@ -382,13 +364,13 @@ struct Memory::Impl {
}
template <typename Callback>
Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size,
Callback&& cb) {
Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
std::size_t size, Callback&& cb) {
class InvalidMemoryException : public std::exception {};
try {
WalkBlock(
dest_addr, size,
process, dest_addr, size,
[&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
GetInteger(current_vaddr));
@@ -405,38 +387,41 @@ struct Memory::Impl {
return ResultSuccess;
}
Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
std::size_t size) {
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
const std::size_t block_size) {
// dc ivac: Invalidate to point of coherency
// GPU flush -> CPU invalidate
HandleRasterizerDownload(GetInteger(current_vaddr), block_size);
};
return PerformCacheOperation(dest_addr, size, on_rasterizer);
return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
}
Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
std::size_t size) {
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
const std::size_t block_size) {
// dc cvac: Store to point of coherency
// CPU flush -> GPU invalidate
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
};
return PerformCacheOperation(dest_addr, size, on_rasterizer);
return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
}
Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
std::size_t size) {
auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
const std::size_t block_size) {
// dc civac: Store to point of coherency, and invalidate from cache
// CPU flush -> GPU invalidate
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
};
return PerformCacheOperation(dest_addr, size, on_rasterizer);
return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
}
void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
if (vaddr == 0 || !AddressSpaceContains(*current_page_table, vaddr, size)) {
if (vaddr == 0) {
return;
}
@@ -463,7 +448,7 @@ struct Memory::Impl {
break;
case Common::PageType::Memory:
current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
0, Common::PageType::DebugMemory);
nullptr, Common::PageType::DebugMemory);
break;
default:
UNREACHABLE();
@@ -481,8 +466,7 @@ struct Memory::Impl {
case Common::PageType::DebugMemory: {
u8* const pointer{GetPointerFromDebugMemory(vaddr & ~YUZU_PAGEMASK)};
current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
reinterpret_cast<uintptr_t>(pointer) - (vaddr & ~YUZU_PAGEMASK),
Common::PageType::Memory);
pointer - (vaddr & ~YUZU_PAGEMASK), Common::PageType::Memory);
break;
}
default:
@@ -493,7 +477,7 @@ struct Memory::Impl {
}
void RasterizerMarkRegionCached(u64 vaddr, u64 size, bool cached) {
if (vaddr == 0 || !AddressSpaceContains(*current_page_table, vaddr, size)) {
if (vaddr == 0) {
return;
}
@@ -522,7 +506,7 @@ struct Memory::Impl {
case Common::PageType::DebugMemory:
case Common::PageType::Memory:
current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
0, Common::PageType::RasterizerCachedMemory);
nullptr, Common::PageType::RasterizerCachedMemory);
break;
case Common::PageType::RasterizerCachedMemory:
// There can be more than one GPU region mapped per CPU region, so it's common
@@ -550,11 +534,10 @@ struct Memory::Impl {
// pagetable after unmapping a VMA. In that case the underlying VMA will no
// longer exist, and we should just leave the pagetable entry blank.
current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
0, Common::PageType::Unmapped);
nullptr, Common::PageType::Unmapped);
} else {
current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
reinterpret_cast<uintptr_t>(pointer) - (vaddr & ~YUZU_PAGEMASK),
Common::PageType::Memory);
pointer - (vaddr & ~YUZU_PAGEMASK), Common::PageType::Memory);
}
break;
}
@@ -601,7 +584,7 @@ struct Memory::Impl {
"Mapping memory page without a pointer @ {:016x}", base * YUZU_PAGESIZE);
while (base != end) {
page_table.pointers[base].Store(0, type);
page_table.pointers[base].Store(nullptr, type);
page_table.backing_addr[base] = 0;
page_table.blocks[base] = 0;
base += 1;
@@ -610,8 +593,7 @@ struct Memory::Impl {
auto orig_base = base;
while (base != end) {
auto host_ptr =
reinterpret_cast<uintptr_t>(system.DeviceMemory().GetPointer<u8>(target)) -
(base << YUZU_PAGEBITS);
system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS);
auto backing = GetInteger(target) - (base << YUZU_PAGEBITS);
page_table.pointers[base].Store(host_ptr, type);
page_table.backing_addr[base] = backing;
@@ -630,15 +612,15 @@ struct Memory::Impl {
// AARCH64 masks the upper 16 bit of all memory accesses
vaddr = vaddr & 0xffffffffffffULL;
if (!AddressSpaceContains(*current_page_table, vaddr, 1)) [[unlikely]] {
if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) {
on_unmapped();
return nullptr;
}
// Avoid adding any extra logic to this fast-path block
const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw();
if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
return reinterpret_cast<u8*>(pointer + vaddr);
if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
return &pointer[vaddr];
}
switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
case Common::PageType::Unmapped:
@@ -826,13 +808,13 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b
bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
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;
if (page >= page_table.pointers.size()) {
return false;
}
const auto [pointer, type] = page_table.pointers[page].PointerType();
return pointer != 0 || type == Common::PageType::RasterizerCachedMemory ||
return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory ||
type == Common::PageType::DebugMemory;
}
@@ -917,14 +899,14 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le
return impl->ReadCString(vaddr, max_length);
}
bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) {
return impl->ReadBlock(src_addr, dest_buffer, size);
impl->ReadBlock(src_addr, dest_buffer, size);
}
bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
const std::size_t size) {
return impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
}
const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
@@ -935,23 +917,23 @@ u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) {
return impl->GetSpan(src_addr, size);
}
bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) {
return impl->WriteBlock(dest_addr, src_buffer, size);
impl->WriteBlock(dest_addr, src_buffer, size);
}
bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
const std::size_t size) {
return impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
}
bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
const std::size_t size) {
return impl->CopyBlock(dest_addr, src_addr, size);
impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size);
}
bool Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
return impl->ZeroBlock(dest_addr, size);
void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size);
}
void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) {
@@ -959,15 +941,15 @@ void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers
}
Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
return impl->InvalidateDataCache(dest_addr, size);
return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size);
}
Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
return impl->StoreDataCache(dest_addr, size);
return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size);
}
Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
return impl->FlushDataCache(dest_addr, size);
return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size);
}
void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {

View File

@@ -24,6 +24,7 @@ class GPUDirtyMemoryManager;
} // namespace Core
namespace Kernel {
class PhysicalMemory;
class KProcess;
} // namespace Kernel
@@ -329,7 +330,7 @@ public:
* @post The range [dest_buffer, size) contains the read bytes from the
* current process' address space.
*/
bool ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
void ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
/**
* Reads a contiguous block of bytes from the current process' address space.
@@ -348,7 +349,7 @@ public:
* @post The range [dest_buffer, size) contains the read bytes from the
* current process' address space.
*/
bool ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
const u8* GetSpan(const VAddr src_addr, const std::size_t size) const;
u8* GetSpan(const VAddr src_addr, const std::size_t size);
@@ -372,7 +373,7 @@ public:
* and will mark that region as invalidated to caches that the active
* graphics backend may be maintaining over the course of execution.
*/
bool WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size);
void WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size);
/**
* Writes a range of bytes into the current process' address space at the specified
@@ -390,7 +391,7 @@ public:
* will be ignored and an error will be logged.
*
*/
bool WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
void WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
std::size_t size);
/**
@@ -404,7 +405,7 @@ public:
* @post The range [dest_addr, size) within the process' address space contains the
* same data within the range [src_addr, size).
*/
bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
std::size_t size);
/**
@@ -417,7 +418,7 @@ public:
* @post The range [dest_addr, size) within the process' address space contains the
* value 0.
*/
bool ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
/**
* Invalidates a range of bytes within the current process' address space at the specified

View File

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

View File

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

View File

@@ -14,12 +14,12 @@
//
#include <deque>
#include <map>
#include <span>
#include <unordered_map>
#include <variant>
#include <vector>
#include <boost/container/flat_map.hpp>
#include "shader_recompiler/frontend/ir/basic_block.h"
#include "shader_recompiler/frontend/ir/opcodes.h"
#include "shader_recompiler/frontend/ir/pred.h"
@@ -52,7 +52,7 @@ struct IndirectBranchVariable {
using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
OverflowFlagTag, GotoVariable, IndirectBranchVariable>;
using ValueMap = std::unordered_map<IR::Block*, IR::Value>;
using ValueMap = boost::container::flat_map<IR::Block*, IR::Value>;
struct DefTable {
const IR::Value& Def(IR::Block* block, IR::Reg variable) {
@@ -112,7 +112,7 @@ struct DefTable {
}
std::array<ValueMap, IR::NUM_USER_PREDS> preds;
std::unordered_map<u32, ValueMap> goto_vars;
boost::container::flat_map<u32, ValueMap> goto_vars;
ValueMap indirect_branch_var;
ValueMap zero_flag;
ValueMap sign_flag;
@@ -295,7 +295,8 @@ private:
return same;
}
std::unordered_map<IR::Block*, std::map<Variant, IR::Inst*>> incomplete_phis;
boost::container::flat_map<IR::Block*, boost::container::flat_map<Variant, IR::Inst*>>
incomplete_phis;
DefTable current_def;
};

View File

@@ -442,11 +442,6 @@ void BufferCache<P>::UnbindComputeStorageBuffers() {
template <class P>
void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, u32 cbuf_offset,
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->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index;
@@ -469,11 +464,6 @@ void BufferCache<P>::UnbindComputeTextureBuffers() {
template <class P>
void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size,
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->written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index;
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_COMPUTE_UNIFORM_BUFFERS = 8;
constexpr u32 NUM_STORAGE_BUFFERS = 16;
constexpr u32 NUM_TEXTURE_BUFFERS = 32;
constexpr u32 NUM_TEXTURE_BUFFERS = 16;
constexpr u32 NUM_STAGES = 5;
using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>;

View File

@@ -103,9 +103,7 @@ public:
explicit QueryCacheBase(VideoCore::RasterizerInterface& rasterizer_,
Core::Memory::Memory& cpu_memory_)
: rasterizer{rasterizer_},
// Use reinterpret_cast instead of static_cast as workaround for
// UBSan bug (https://github.com/llvm/llvm-project/issues/59060)
cpu_memory{cpu_memory_}, streams{{CounterStream{reinterpret_cast<QueryCache&>(*this),
cpu_memory{cpu_memory_}, streams{{CounterStream{static_cast<QueryCache&>(*this),
VideoCore::QueryType::SamplesPassed}}} {
(void)slot_async_jobs.insert(); // Null value
}

Some files were not shown because too many files have changed in this diff Show More