Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8892eb0
Fix `MoveRegister` to clear when value is 0
PixelyIon Nov 5, 2022
f4a8328
Implement Symbol Hooking
PixelyIon Nov 7, 2022
3882457
Restructure ConditionalVariableSignal to avoid potential deadlock
bylaws Oct 25, 2022
5c76a57
Use `NestedScrollView` for licence dialogs and minor layout tweaks
nickbeth Jan 19, 2022
dec04db
`AppListItem` misc tweaks
nickbeth Jan 21, 2022
f63fdf2
Partially revert 'Make all `Dialog`s use `@color/backgroundColor` as …
nickbeth Jan 21, 2022
6848e69
Improve design consistency across the app
nickbeth Jan 21, 2022
f93d3b7
Add a drag indicator element at the top of LicenceDialog
nickbeth Jan 25, 2022
6a6e89f
Make `BottomSheetDialog` go fullscreen when fully expanded
nickbeth Jan 25, 2022
86364a8
Allow content to be drawn behind the navigation bar
nickbeth Nov 4, 2022
4146261
Create a unified style for section titles
nickbeth Feb 16, 2022
e2a5da1
Fix `AppDialog` layout
nickbeth Nov 5, 2022
56f6f8a
Reword the unsupported gpu drivers message
nickbeth Nov 7, 2022
281562c
Fix FABs ripple effect in `OnScreenEditActivity`
nickbeth Nov 7, 2022
cc71e7b
Run emulation in a separate process
nickbeth Oct 21, 2022
7f24c7b
Store KMemory object ptrs in memory class to avoid linear-time unmap
bylaws Oct 30, 2022
ec139b3
Fixup CancelBuffer fence handling
bylaws Oct 30, 2022
29e89a3
Fix crashes when opening non-existent directories
bylaws Oct 30, 2022
001064b
Fix GraphicsBufferProducer recreation
bylaws Oct 30, 2022
f650f32
Avoid duplicating NvDrv buffer unmap code
bylaws Oct 30, 2022
cd0b263
Prevent truncation of big page start in GetVaRegions
bylaws Oct 30, 2022
8b523fa
Avoid inline syncpt increments sending OOB GpEntries
bylaws Oct 30, 2022
e7bab27
Fixup nvdrv channel private memory allocation
bylaws Oct 30, 2022
021f82e
Stub ListOpenContextStoredUsers
bylaws Oct 30, 2022
1fc2641
Stub the web applet
bylaws Oct 30, 2022
e571066
Stub ldr:ro IRoInterface
bylaws Sep 29, 2022
01e27bd
Implement ldr:ro LoadModule
bylaws Oct 30, 2022
9afa8b8
Stub nsd:u/nsd:a and sfdnsres services
dima-xd Oct 31, 2022
262ee28
Stub some bsd functions
dima-xd Nov 1, 2022
7609047
Stub some account functions
dima-xd Nov 2, 2022
cd8e125
Stub TryPopFromFriendInvitationStorageChannel
dima-xd Nov 3, 2022
636ad62
Stub CheckFreeCommunicationPermission and IsFreeCommunicationAvailable
dima-xd Nov 3, 2022
12382ea
Stub GetFriendList
dima-xd Nov 3, 2022
3822371
Stub GetAccountId
dima-xd Nov 3, 2022
35f4de1
Stub GetAddOnContentListChangedEventWithProcessId
dima-xd Nov 12, 2022
dd3d11e
Stub GetPreviousProgramIndex
dima-xd Nov 12, 2022
1823d2f
Stub GetBlockedUserListIds and UpdateUserPresence
dima-xd Nov 12, 2022
f9f199c
Stub SetIdleTimeDetectionExtension, SetAlbumImageTakenNotificationEna…
dima-xd Nov 12, 2022
f86cd49
Stub IsLargeResourceAvailable
dima-xd Nov 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ add_library(skyline SHARED
${source_DIR}/skyline/loader/nca.cpp
${source_DIR}/skyline/loader/xci.cpp
${source_DIR}/skyline/loader/nsp.cpp
${source_DIR}/skyline/hle/symbol_hooks.cpp
${source_DIR}/skyline/vfs/partition_filesystem.cpp
${source_DIR}/skyline/vfs/ctr_encrypted_backing.cpp
${source_DIR}/skyline/vfs/rom_filesystem.cpp
Expand Down Expand Up @@ -287,10 +288,12 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/bt/IBluetoothUser.cpp
${source_DIR}/skyline/services/btm/IBtmUser.cpp
${source_DIR}/skyline/services/btm/IBtmUserCore.cpp
${source_DIR}/skyline/services/ro/IRoInterface.cpp
${source_DIR}/skyline/applet/applet_creator.cpp
${source_DIR}/skyline/applet/controller_applet.cpp
${source_DIR}/skyline/applet/error_applet.cpp
${source_DIR}/skyline/applet/player_select_applet.cpp
${source_DIR}/skyline/applet/web_applet.cpp
${source_DIR}/skyline/applet/swkbd/software_keyboard_applet.cpp
${source_DIR}/skyline/applet/swkbd/software_keyboard_config.cpp
${source_DIR}/skyline/services/codec/IHardwareOpusDecoder.cpp
Expand Down Expand Up @@ -360,6 +363,8 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/nim/IShopServiceAccessServerInterface.cpp
${source_DIR}/skyline/services/nim/IShopServiceAsync.cpp
${source_DIR}/skyline/services/socket/bsd/IClient.cpp
${source_DIR}/skyline/services/socket/nsd/IManager.cpp
${source_DIR}/skyline/services/socket/sfdnsres/IResolver.cpp
${source_DIR}/skyline/services/spl/IRandomInterface.cpp
${source_DIR}/skyline/services/ssl/ISslService.cpp
${source_DIR}/skyline/services/ssl/ISslContext.cpp
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
android:configChanges="orientation|screenSize|uiMode"
android:exported="true"
android:launchMode="singleTask"
android:process=":emulationProcess"
android:parentActivityName=".MainActivity">

<intent-filter>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/cpp/skyline/applet/applet_creator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "controller_applet.h"
#include "error_applet.h"
#include "player_select_applet.h"
#include "web_applet.h"
#include "swkbd/software_keyboard_applet.h"

namespace skyline::applet {
Expand All @@ -23,6 +24,8 @@ namespace skyline::applet {
return std::make_shared<swkbd::SoftwareKeyboardApplet>(state, manager, std::move(onAppletStateChanged), std::move(onNormalDataPushFromApplet), std::move(onInteractiveDataPushFromApplet), appletMode);
case AppletId::LibraryAppletError:
return std::make_shared<ErrorApplet>(state, manager, std::move(onAppletStateChanged), std::move(onNormalDataPushFromApplet), std::move(onInteractiveDataPushFromApplet), appletMode);
case AppletId::LibraryAppletOfflineWeb:
return std::make_shared<WebApplet>(state, manager, std::move(onAppletStateChanged), std::move(onNormalDataPushFromApplet), std::move(onInteractiveDataPushFromApplet), appletMode);
default:
throw exception{"Unimplemented Applet: 0x{:X} ({})", static_cast<u32>(appletId), ToString(appletId)};
}
Expand Down
47 changes: 47 additions & 0 deletions app/src/main/cpp/skyline/applet/web_applet.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
// Copyright © 2020 yuzu Emulator Project (https://github.com/yuzu-emu/)

#include <input.h>
#include <input/npad.h>
#include <services/applet/common_arguments.h>
#include <services/am/storage/ObjIStorage.h>
#include "web_applet.h"

namespace skyline::applet {
WebApplet::WebApplet(const DeviceState &state,
service::ServiceManager &manager,
std::shared_ptr<kernel::type::KEvent> onAppletStateChanged,
std::shared_ptr<kernel::type::KEvent> onNormalDataPushFromApplet,
std::shared_ptr<kernel::type::KEvent> onInteractiveDataPushFromApplet,
service::applet::LibraryAppletMode appletMode)
: IApplet{state, manager, std::move(onAppletStateChanged), std::move(onNormalDataPushFromApplet), std::move(onInteractiveDataPushFromApplet), appletMode} {}

Result WebApplet::Start() {
auto commonArg{PopNormalInput<service::applet::CommonArguments>()};
auto argHeader{PopNormalInput<WebArgHeader>()};

if ((commonArg.apiVersion >= 0x80000 && argHeader.shimKind == ShimKind::Web) || (commonArg.apiVersion >= 0x30000 && argHeader.shimKind == ShimKind::Share))
Logger::Error("OfflineWeb TLV output is unsupported!");

PushNormalDataAndSignal(std::make_shared<service::am::ObjIStorage<WebCommonReturnValue>>(state, manager, WebCommonReturnValue{
.exitReason = WebExitReason::WindowClosed,
.lastUrl = {'h', 't', 't', 'p', ':', '/', '/', 'l', 'o', 'c', 'a', 'l', 'h', 'o', 's', 't', '/'},
.lastUrlSize = 17
}));

// Notify the guest that we've finished running
onAppletStateChanged->Signal();
return {};
}

Result WebApplet::GetResult() {
return {};
}

void WebApplet::PushNormalDataToApplet(std::shared_ptr<service::am::IStorage> data) {
PushNormalInput(data);
}

void WebApplet::PushInteractiveDataToApplet(std::shared_ptr<service::am::IStorage> data) {}
}
75 changes: 75 additions & 0 deletions app/src/main/cpp/skyline/applet/web_applet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
// Copyright © 2020 Ryujinx Team and Contributors (https://github.com/ryujinx/)

#pragma once

#include <services/am/applet/IApplet.h>

namespace skyline::applet {
/**
* @brief The Web applet is utilized by the guest to display web pages using the built-in web browser
*/
class WebApplet : public service::am::IApplet, service::am::EnableNormalQueue {
private:
#pragma pack(push, 1)

/**
* @brief Type of web-applet to launch
* @url https://switchbrew.org/wiki/Internet_Browser#ShimKind
*/
enum class ShimKind : u32 {
Shop = 1,
Login = 2,
Offline = 3,
Share = 4,
Web = 5,
Wifi = 6,
Lobby = 7,
Lhub = 8,
};

enum class WebExitReason : u32 {
EndButtonPressed = 0,
BackButtonPressed = 1,
ExitRequested = 2,
CallbackURL = 3,
WindowClosed = 4,
ErrorDialog = 7,
};

/**
* @brief Common return value struct for all web-applet commands
*/
struct WebCommonReturnValue {
WebExitReason exitReason;
u32 _pad_;
std::array<char, 0x1000> lastUrl;
u64 lastUrlSize;
};
static_assert(sizeof(WebCommonReturnValue) == 0x1010);

/**
* @brief The input data for the web-applet
*/
struct WebArgHeader {
u16 count;
u16 _pad_;
ShimKind shimKind;
};

#pragma pack(pop)


public:
WebApplet(const DeviceState &state, service::ServiceManager &manager, std::shared_ptr<kernel::type::KEvent> onAppletStateChanged, std::shared_ptr<kernel::type::KEvent> onNormalDataPushFromApplet, std::shared_ptr<kernel::type::KEvent> onInteractiveDataPushFromApplet, service::applet::LibraryAppletMode appletMode);

Result Start() override;

Result GetResult() override;

void PushNormalDataToApplet(std::shared_ptr<service::am::IStorage> data) override;

void PushInteractiveDataToApplet(std::shared_ptr<service::am::IStorage> data) override;
};
}
1 change: 1 addition & 0 deletions app/src/main/cpp/skyline/common/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
PERFETTO_DEFINE_CATEGORIES(
perfetto::Category("scheduler").SetDescription("Events from the HLE scheduler"),
perfetto::Category("kernel").SetDescription("Events from parts of the HLE kernel"),
perfetto::Category("hook").SetDescription("Events from HLE hooks"),
perfetto::Category("guest").SetDescription("Events relating to guest code"),
perfetto::Category("host").SetDescription("Events relating to host code"),
perfetto::Category("gpu").SetDescription("Events from the emulated GPU"),
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/cpp/skyline/common/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,12 @@ namespace skyline::util {
FillRandomBytes(std::span(reinterpret_cast<typename IntegerFor<T>::Type *>(&object), IntegerFor<T>::Count));
}

template<IsPointerOrUnsignedIntegral T>
T RandomNumber(T min, T max) {
std::uniform_int_distribution dist(PointerValue(min), PointerValue(max));
return ValuePointer<T>(dist(detail::generator));
}

/**
* @brief A temporary shim for C++ 20's bit_cast to make transitioning to it easier
*/
Expand Down Expand Up @@ -353,4 +359,8 @@ namespace skyline::util {
std::array<T, Size> MergeInto(TSrcs &&... srcs) {
return MergeInto<T>(std::make_index_sequence<Size>(), std::forward<TSrcs>(srcs)...);
}

inline std::string HexDump(std::span<u8> data) {
return std::accumulate(data.begin(), data.end(), std::string{}, [](std::string str, u8 el) { return std::move(str) + fmt::format("{:02X}", el); });
}
}
17 changes: 17 additions & 0 deletions app/src/main/cpp/skyline/hle/symbol_hook_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)

#pragma once

#include "symbol_hooks.h"

namespace skyline::hle {
struct HookTableEntry {
std::string_view name; //!< The name of the symbol
HookType hook; //!< The hook that the symbol should include

HookTableEntry(std::string_view name, HookType hook) : name{name}, hook{std::move(hook)} {}
};

static std::array<HookTableEntry, 0> HookedSymbols{};
}
16 changes: 16 additions & 0 deletions app/src/main/cpp/skyline/hle/symbol_hooks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)

#include <cxxabi.h>
#include "symbol_hooks.h"

namespace skyline::hle {
std::string Demangle(const std::string_view mangledName) {
int status{};
size_t length{};
std::unique_ptr<char, decltype(&std::free)> demangled{abi::__cxa_demangle(mangledName.data(), nullptr, &length, &status), std::free};
return std::string{status == 0 ? std::string_view{demangled.get()} : mangledName};
}

HookedSymbol::HookedSymbol(std::string pName, HookType hook) : name{std::move(pName)}, prettyName{Demangle(name)}, hook{std::move(hook)} {}
}
29 changes: 29 additions & 0 deletions app/src/main/cpp/skyline/hle/symbol_hooks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)

#pragma once

#include <common.h>

namespace skyline::hle {
struct HookedSymbol;

using HookFunction = std::function<void(const DeviceState &, const HookedSymbol &)>;

using OverrideHook = HookFunction; //!< A function that overrides the execution of a hooked function

struct EntryExitHook {
HookFunction entry; //!< The hook to be called when the function is entered
HookFunction exit; //!< The hook to be called when the function is exited
};

using HookType = std::variant<OverrideHook, EntryExitHook>;

struct HookedSymbol {
std::string name; //!< The name of the symbol
std::string prettyName; //!< The demangled name of the symbol
HookType hook; //!< The hook that the symbol should include

HookedSymbol(std::string name, HookType hook);
};
}
1 change: 1 addition & 0 deletions app/src/main/cpp/skyline/kernel/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ namespace skyline::kernel {
lower->state = chunk.state;
lower->permission = chunk.permission;
lower->attributes = chunk.attributes;
lower->memory = chunk.memory;
} else if (lower->ptr + lower->size > chunk.ptr + chunk.size) {
auto lowerExtension{*lower};
lowerExtension.ptr = chunk.ptr + chunk.size;
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/cpp/skyline/kernel/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include <common/file_descriptor.h>

namespace skyline {
namespace kernel::type {
class KMemory;
}

namespace memory {
union Permission {
/**
Expand Down Expand Up @@ -195,9 +199,10 @@ namespace skyline {
memory::Permission permission;
memory::MemoryState state;
memory::MemoryAttribute attributes;
kernel::type::KMemory *memory{};

constexpr bool IsCompatible(const ChunkDescriptor &chunk) const {
return chunk.permission == permission && chunk.state.value == state.value && chunk.attributes.value == attributes.value;
return chunk.permission == permission && chunk.state.value == state.value && chunk.attributes.value == attributes.value && chunk.memory == memory;
}
};

Expand Down
25 changes: 14 additions & 11 deletions app/src/main/cpp/skyline/kernel/svc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1067,20 +1067,23 @@ namespace skyline::kernel::svc {

auto end{pointer + size};
while (pointer < end) {
auto memory{state.process->GetMemoryObject(pointer)};
if (memory) {
auto item{static_pointer_cast<type::KPrivateMemory>(memory->item)};
auto initialSize{item->guest.size()};
if (item->memoryState == memory::states::Heap) {
if (item->guest.data() >= pointer) {
if (item->guest.size() <= size) {
item->Resize(0);
auto chunk{state.process->memory.Get(pointer)};
if (chunk && chunk->memory) {
if (chunk->memory->objectType != type::KType::KPrivateMemory)
throw exception("Trying to unmap non-private memory");

auto memory{static_cast<type::KPrivateMemory *>(chunk->memory)};
auto initialSize{memory->guest.size()};
if (memory->memoryState == memory::states::Heap) {
if (memory->guest.data() >= pointer) {
if (memory->guest.size() <= size) {
memory->Resize(0);
state.process->CloseHandle(memory->handle);
} else {
item->Remap(span<u8>{pointer + size, static_cast<size_t>((pointer + item->guest.size() - item->guest.data())) - size});
memory->Remap(span<u8>{pointer + size, static_cast<size_t>((pointer + memory->guest.size() - memory->guest.data())) - size});
}
} else if (item->guest.data() < pointer) {
item->Resize(static_cast<size_t>(pointer - item->guest.data()));
} else if (memory->guest.data() < pointer) {
memory->Resize(static_cast<size_t>(pointer - memory->guest.data()));
}
}
pointer += initialSize;
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/cpp/skyline/kernel/types/KPrivateMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
#include "KProcess.h"

namespace skyline::kernel::type {
KPrivateMemory::KPrivateMemory(const DeviceState &state, span<u8> guest, memory::Permission permission, memory::MemoryState memState)
KPrivateMemory::KPrivateMemory(const DeviceState &state, KHandle handle, span<u8> guest, memory::Permission permission, memory::MemoryState memState)
: permission(permission),
memoryState(memState),
handle(handle),
KMemory(state, KType::KPrivateMemory, guest) {
if (!state.process->memory.base.contains(guest))
throw exception("KPrivateMemory allocation isn't inside guest address space: 0x{:X} - 0x{:X}", guest.data(), guest.data() + guest.size());
if (!util::IsPageAligned(guest.data()) || !util::IsPageAligned(guest.size()))
throw exception("KPrivateMemory mapping isn't page-aligned: 0x{:X} - 0x{:X} (0x{:X})", guest.data(), guest.data() + guest.size());
throw exception("KPrivateMemory mapping isn't page-aligned: 0x{:X} - 0x{:X} (0x{:X})", guest.data(), guest.data() + guest.size(), guest.size());

if (mprotect(guest.data(), guest.size(), PROT_READ | PROT_WRITE | PROT_EXEC) < 0) // We only need to reprotect as the allocation has already been reserved by the MemoryManager
throw exception("An occurred while mapping private memory: {} with 0x{:X} @ 0x{:X}", strerror(errno), guest.data(), guest.size());
Expand All @@ -25,6 +26,7 @@ namespace skyline::kernel::type {
.size = guest.size(),
.permission = permission,
.state = memState,
.memory = this,
});
}

Expand All @@ -44,6 +46,7 @@ namespace skyline::kernel::type {
.size = nSize - guest.size(),
.permission = permission,
.state = memoryState,
.memory = this,
});
}
guest = span<u8>{guest.data(), nSize};
Expand Down Expand Up @@ -78,6 +81,7 @@ namespace skyline::kernel::type {
.size = size,
.permission = pPermission,
.state = memoryState,
.memory = this,
});
}

Expand Down
3 changes: 2 additions & 1 deletion app/src/main/cpp/skyline/kernel/types/KPrivateMemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ namespace skyline::kernel::type {
public:
memory::Permission permission;
memory::MemoryState memoryState;
KHandle handle;

/**
* @param permission The permissions for the allocated memory (As reported to the application, host memory permissions aren't reflected by this)
* @note 'ptr' needs to be in guest-reserved address space
*/
KPrivateMemory(const DeviceState &state, span<u8> guest, memory::Permission permission, memory::MemoryState memState);
KPrivateMemory(const DeviceState &state, KHandle handle, span<u8> guest, memory::Permission permission, memory::MemoryState memState);

/**
* @note There is no check regarding if any expansions will cause the memory mapping to leak into other mappings
Expand Down
Loading