summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/k_page_table.cpp5
-rw-r--r--src/core/hle/kernel/kernel.cpp16
-rw-r--r--src/core/hle/service/acc/acc.cpp43
-rw-r--r--src/core/hle/service/acc/acc.h3
-rw-r--r--src/core/hle/service/acc/acc_su.cpp6
-rw-r--r--src/core/hle/service/acc/profile_manager.h3
-rw-r--r--src/core/hle/service/am/am.cpp41
-rw-r--r--src/core/hle/service/am/am.h3
-rw-r--r--src/core/hle/service/caps/caps.cpp2
-rw-r--r--src/core/hle/service/caps/caps_a.cpp4
-rw-r--r--src/core/hle/service/caps/caps_manager.cpp86
-rw-r--r--src/core/hle/service/caps/caps_manager.h9
-rw-r--r--src/core/hle/service/caps/caps_types.h14
-rw-r--r--src/core/hle/service/caps/caps_u.cpp74
-rw-r--r--src/core/hle/service/jit/jit_context.cpp36
15 files changed, 274 insertions, 71 deletions
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 1fbfbf31f..0b0cef984 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -3405,6 +3405,11 @@ Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_K
new_attr, KMemoryBlockDisableMergeAttribute::Locked,
KMemoryBlockDisableMergeAttribute::None);
+ // If we have an output page group, open.
+ if (out_pg) {
+ out_pg->Open();
+ }
+
R_SUCCEED();
}
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index a1134b7e2..cb025c3d6 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -373,7 +373,7 @@ struct KernelCore::Impl {
static inline thread_local u8 host_thread_id = UINT8_MAX;
/// Sets the host thread ID for the caller.
- u32 SetHostThreadId(std::size_t core_id) {
+ LTO_NOINLINE u32 SetHostThreadId(std::size_t core_id) {
// This should only be called during core init.
ASSERT(host_thread_id == UINT8_MAX);
@@ -384,13 +384,13 @@ struct KernelCore::Impl {
}
/// Gets the host thread ID for the caller
- u32 GetHostThreadId() const {
+ LTO_NOINLINE u32 GetHostThreadId() const {
return host_thread_id;
}
// Gets the dummy KThread for the caller, allocating a new one if this is the first time
- KThread* GetHostDummyThread(KThread* existing_thread) {
- const auto initialize{[](KThread* thread) {
+ LTO_NOINLINE KThread* GetHostDummyThread(KThread* existing_thread) {
+ const auto initialize{[](KThread* thread) LTO_NOINLINE {
ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
return thread;
}};
@@ -424,11 +424,11 @@ struct KernelCore::Impl {
static inline thread_local bool is_phantom_mode_for_singlecore{false};
- bool IsPhantomModeForSingleCore() const {
+ LTO_NOINLINE bool IsPhantomModeForSingleCore() const {
return is_phantom_mode_for_singlecore;
}
- void SetIsPhantomModeForSingleCore(bool value) {
+ LTO_NOINLINE void SetIsPhantomModeForSingleCore(bool value) {
ASSERT(!is_multicore);
is_phantom_mode_for_singlecore = value;
}
@@ -439,14 +439,14 @@ struct KernelCore::Impl {
static inline thread_local KThread* current_thread{nullptr};
- KThread* GetCurrentEmuThread() {
+ LTO_NOINLINE KThread* GetCurrentEmuThread() {
if (!current_thread) {
current_thread = GetHostDummyThread(nullptr);
}
return current_thread;
}
- void SetCurrentEmuThread(KThread* thread) {
+ LTO_NOINLINE void SetCurrentEmuThread(KThread* thread) {
current_thread = thread;
}
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index b971401e6..b7d14060c 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -49,7 +49,7 @@ public:
: ServiceFramework{system_, "IManagerForSystemService"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "CheckAvailability"},
+ {0, &IManagerForSystemService::CheckAvailability, "CheckAvailability"},
{1, nullptr, "GetAccountId"},
{2, nullptr, "EnsureIdTokenCacheAsync"},
{3, nullptr, "LoadIdTokenCache"},
@@ -78,6 +78,13 @@ public:
RegisterHandlers(functions);
}
+
+private:
+ void CheckAvailability(HLERequestContext& ctx) {
+ LOG_WARNING(Service_ACC, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
};
// 3.0.0+
@@ -837,6 +844,29 @@ void Module::Interface::InitializeApplicationInfoV2(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void Module::Interface::BeginUserRegistration(HLERequestContext& ctx) {
+ const auto user_id = Common::UUID::MakeRandom();
+ profile_manager->CreateNewUser(user_id, "yuzu");
+
+ LOG_INFO(Service_ACC, "called, uuid={}", user_id.FormattedString());
+
+ IPC::ResponseBuilder rb{ctx, 6};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(user_id);
+}
+
+void Module::Interface::CompleteUserRegistration(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ Common::UUID user_id = rp.PopRaw<Common::UUID>();
+
+ LOG_INFO(Service_ACC, "called, uuid={}", user_id.FormattedString());
+
+ profile_manager->WriteUserSaveFile();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void Module::Interface::GetProfileEditor(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
Common::UUID user_id = rp.PopRaw<Common::UUID>();
@@ -880,6 +910,17 @@ void Module::Interface::StoreSaveDataThumbnailApplication(HLERequestContext& ctx
StoreSaveDataThumbnail(ctx, uuid, tid);
}
+void Module::Interface::GetBaasAccountManagerForSystemService(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto uuid = rp.PopRaw<Common::UUID>();
+
+ LOG_INFO(Service_ACC, "called, uuid=0x{}", uuid.RawString());
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(ResultSuccess);
+ rb.PushIpcInterface<IManagerForSystemService>(system, uuid);
+}
+
void Module::Interface::StoreSaveDataThumbnailSystem(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto uuid = rp.PopRaw<Common::UUID>();
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index 6b4735c2f..0395229b4 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -33,10 +33,13 @@ public:
void TrySelectUserWithoutInteraction(HLERequestContext& ctx);
void IsUserAccountSwitchLocked(HLERequestContext& ctx);
void InitializeApplicationInfoV2(HLERequestContext& ctx);
+ void BeginUserRegistration(HLERequestContext& ctx);
+ void CompleteUserRegistration(HLERequestContext& ctx);
void GetProfileEditor(HLERequestContext& ctx);
void ListQualifiedUsers(HLERequestContext& ctx);
void ListOpenContextStoredUsers(HLERequestContext& ctx);
void StoreSaveDataThumbnailApplication(HLERequestContext& ctx);
+ void GetBaasAccountManagerForSystemService(HLERequestContext& ctx);
void StoreSaveDataThumbnailSystem(HLERequestContext& ctx);
private:
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp
index d9882ecd3..770d13ec5 100644
--- a/src/core/hle/service/acc/acc_su.cpp
+++ b/src/core/hle/service/acc/acc_su.cpp
@@ -23,7 +23,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
{99, nullptr, "DebugActivateOpenContextRetention"},
{100, nullptr, "GetUserRegistrationNotifier"},
{101, nullptr, "GetUserStateChangeNotifier"},
- {102, nullptr, "GetBaasAccountManagerForSystemService"},
+ {102, &ACC_SU::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"},
{103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
{104, nullptr, "GetProfileUpdateNotifier"},
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
@@ -40,8 +40,8 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
{152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"},
{190, nullptr, "GetUserLastOpenedApplication"},
{191, nullptr, "ActivateOpenContextHolder"},
- {200, nullptr, "BeginUserRegistration"},
- {201, nullptr, "CompleteUserRegistration"},
+ {200, &ACC_SU::BeginUserRegistration, "BeginUserRegistration"},
+ {201, &ACC_SU::CompleteUserRegistration, "CompleteUserRegistration"},
{202, nullptr, "CancelUserRegistration"},
{203, nullptr, "DeleteUser"},
{204, nullptr, "SetUserPosition"},
diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h
index 993a5a57a..900e32200 100644
--- a/src/core/hle/service/acc/profile_manager.h
+++ b/src/core/hle/service/acc/profile_manager.h
@@ -96,9 +96,10 @@ public:
bool SetProfileBaseAndData(Common::UUID uuid, const ProfileBase& profile_new,
const UserData& data_new);
+ void WriteUserSaveFile();
+
private:
void ParseUserSaveFile();
- void WriteUserSaveFile();
std::optional<std::size_t> AddToProfiles(const ProfileInfo& profile);
bool RemoveProfileAtIndex(std::size_t index);
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index ac376b55a..98765b81a 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -210,8 +210,8 @@ IDisplayController::IDisplayController(Core::System& system_)
{21, nullptr, "ClearAppletTransitionBuffer"},
{22, nullptr, "AcquireLastApplicationCaptureSharedBuffer"},
{23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"},
- {24, nullptr, "AcquireLastForegroundCaptureSharedBuffer"},
- {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"},
+ {24, &IDisplayController::AcquireLastForegroundCaptureSharedBuffer, "AcquireLastForegroundCaptureSharedBuffer"},
+ {25, &IDisplayController::ReleaseLastForegroundCaptureSharedBuffer, "ReleaseLastForegroundCaptureSharedBuffer"},
{26, &IDisplayController::AcquireCallerAppletCaptureSharedBuffer, "AcquireCallerAppletCaptureSharedBuffer"},
{27, &IDisplayController::ReleaseCallerAppletCaptureSharedBuffer, "ReleaseCallerAppletCaptureSharedBuffer"},
{28, nullptr, "TakeScreenShotOfOwnLayerEx"},
@@ -239,6 +239,22 @@ void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void IDisplayController::AcquireLastForegroundCaptureSharedBuffer(HLERequestContext& ctx) {
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push(1U);
+ rb.Push(0);
+}
+
+void IDisplayController::ReleaseLastForegroundCaptureSharedBuffer(HLERequestContext& ctx) {
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void IDisplayController::AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
@@ -1557,7 +1573,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
{100, nullptr, "CreateGameMovieTrimmer"},
{101, nullptr, "ReserveResourceForMovieOperation"},
{102, nullptr, "UnreserveResourceForMovieOperation"},
- {110, nullptr, "GetMainAppletAvailableUsers"},
+ {110, &ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers, "GetMainAppletAvailableUsers"},
{120, nullptr, "GetLaunchStorageInfoForDebug"},
{130, nullptr, "GetGpuErrorDetectedSystemEvent"},
{140, nullptr, "SetApplicationMemoryReservation"},
@@ -1652,6 +1668,25 @@ void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext&
rb.PushRaw(applet_info);
}
+void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext& ctx) {
+ const Service::Account::ProfileManager manager{};
+ bool is_empty{true};
+ s32 user_count{-1};
+
+ LOG_INFO(Service_AM, "called");
+
+ if (manager.GetUserCount() > 0) {
+ is_empty = false;
+ user_count = static_cast<s32>(manager.GetUserCount());
+ ctx.WriteBuffer(manager.GetAllUsers());
+ }
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<u8>(is_empty);
+ rb.Push(user_count);
+}
+
void ILibraryAppletSelfAccessor::PushInShowAlbum() {
const Applets::CommonArguments arguments{
.arguments_version = Applets::CommonArgumentVersion::Version3,
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 4a045cfd4..64b3f3fe2 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -124,6 +124,8 @@ public:
private:
void GetCallerAppletCaptureImageEx(HLERequestContext& ctx);
void TakeScreenShotOfOwnLayer(HLERequestContext& ctx);
+ void AcquireLastForegroundCaptureSharedBuffer(HLERequestContext& ctx);
+ void ReleaseLastForegroundCaptureSharedBuffer(HLERequestContext& ctx);
void AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx);
void ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx);
};
@@ -345,6 +347,7 @@ private:
void GetLibraryAppletInfo(HLERequestContext& ctx);
void ExitProcessAndReturn(HLERequestContext& ctx);
void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
+ void GetMainAppletAvailableUsers(HLERequestContext& ctx);
void PushInShowAlbum();
void PushInShowCabinetData();
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp
index 286f9fd10..31dd98140 100644
--- a/src/core/hle/service/caps/caps.cpp
+++ b/src/core/hle/service/caps/caps.cpp
@@ -16,7 +16,7 @@ namespace Service::Capture {
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
- auto album_manager = std::make_shared<AlbumManager>();
+ auto album_manager = std::make_shared<AlbumManager>(system);
server_manager->RegisterNamedService(
"caps:a", std::make_shared<IAlbumAccessorService>(system, album_manager));
diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp
index e22f72bf6..9925720a3 100644
--- a/src/core/hle/service/caps/caps_a.cpp
+++ b/src/core/hle/service/caps/caps_a.cpp
@@ -128,9 +128,9 @@ void IAlbumAccessorService::GetAlbumFileListEx0(HLERequestContext& ctx) {
ctx.WriteBuffer(entries);
}
- IPC::ResponseBuilder rb{ctx, 3};
+ IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
- rb.Push(entries.size());
+ rb.Push<u64>(entries.size());
}
void IAlbumAccessorService::GetAutoSavingStorage(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp
index 2df6a930a..2b4e3f076 100644
--- a/src/core/hle/service/caps/caps_manager.cpp
+++ b/src/core/hle/service/caps/caps_manager.cpp
@@ -8,12 +8,15 @@
#include "common/fs/file.h"
#include "common/fs/path_util.h"
#include "common/logging/log.h"
+#include "core/core.h"
#include "core/hle/service/caps/caps_manager.h"
#include "core/hle/service/caps/caps_result.h"
+#include "core/hle/service/time/time_manager.h"
+#include "core/hle/service/time/time_zone_content_manager.h"
namespace Service::Capture {
-AlbumManager::AlbumManager() {}
+AlbumManager::AlbumManager(Core::System& system_) : system{system_} {}
AlbumManager::~AlbumManager() = default;
@@ -83,6 +86,34 @@ Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, Albu
}
Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries,
+ ContentType contex_type, s64 start_posix_time,
+ s64 end_posix_time, u64 aruid) const {
+ if (!is_mounted) {
+ return ResultIsNotMounted;
+ }
+
+ std::vector<ApplicationAlbumEntry> album_entries;
+ const auto start_date = ConvertToAlbumDateTime(start_posix_time);
+ const auto end_date = ConvertToAlbumDateTime(end_posix_time);
+ const auto result = GetAlbumFileList(album_entries, contex_type, start_date, end_date, aruid);
+
+ if (result.IsError()) {
+ return result;
+ }
+
+ for (const auto& album_entry : album_entries) {
+ ApplicationAlbumFileEntry entry{
+ .entry = album_entry,
+ .datetime = album_entry.datetime,
+ .unknown = {},
+ };
+ out_entries.push_back(entry);
+ }
+
+ return ResultSuccess;
+}
+
+Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries,
ContentType contex_type, AlbumFileDateTime start_date,
AlbumFileDateTime end_date, u64 aruid) const {
if (!is_mounted) {
@@ -93,31 +124,25 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& ou
if (file_id.type != contex_type) {
continue;
}
-
if (file_id.date > start_date) {
continue;
}
-
if (file_id.date < end_date) {
continue;
}
-
if (out_entries.size() >= SdAlbumFileLimit) {
break;
}
const auto entry_size = Common::FS::GetSize(path);
- ApplicationAlbumFileEntry entry{.entry =
- {
- .size = entry_size,
- .hash{},
- .datetime = file_id.date,
- .storage = file_id.storage,
- .content = contex_type,
- .unknown = 1,
- },
- .datetime = file_id.date,
- .unknown = {}};
+ ApplicationAlbumEntry entry{
+ .size = entry_size,
+ .hash{},
+ .datetime = file_id.date,
+ .storage = file_id.storage,
+ .content = contex_type,
+ .unknown = 1,
+ };
out_entries.push_back(entry);
}
@@ -274,12 +299,12 @@ Result AlbumManager::GetAlbumEntry(AlbumEntry& out_entry, const std::filesystem:
.application_id = static_cast<u64>(std::stoll(application, 0, 16)),
.date =
{
- .year = static_cast<u16>(std::stoi(year)),
- .month = static_cast<u8>(std::stoi(month)),
- .day = static_cast<u8>(std::stoi(day)),
- .hour = static_cast<u8>(std::stoi(hour)),
- .minute = static_cast<u8>(std::stoi(minute)),
- .second = static_cast<u8>(std::stoi(second)),
+ .year = static_cast<s16>(std::stoi(year)),
+ .month = static_cast<s8>(std::stoi(month)),
+ .day = static_cast<s8>(std::stoi(day)),
+ .hour = static_cast<s8>(std::stoi(hour)),
+ .minute = static_cast<s8>(std::stoi(minute)),
+ .second = static_cast<s8>(std::stoi(second)),
.unique_id = 0,
},
.storage = AlbumStorage::Sd,
@@ -339,4 +364,23 @@ Result AlbumManager::LoadImage(std::span<u8> out_image, const std::filesystem::p
return ResultSuccess;
}
+
+AlbumFileDateTime AlbumManager::ConvertToAlbumDateTime(u64 posix_time) const {
+ Time::TimeZone::CalendarInfo calendar_date{};
+ const auto& time_zone_manager =
+ system.GetTimeManager().GetTimeZoneContentManager().GetTimeZoneManager();
+
+ time_zone_manager.ToCalendarTimeWithMyRules(posix_time, calendar_date);
+
+ return {
+ .year = calendar_date.time.year,
+ .month = calendar_date.time.month,
+ .day = calendar_date.time.day,
+ .hour = calendar_date.time.hour,
+ .minute = calendar_date.time.minute,
+ .second = calendar_date.time.second,
+ .unique_id = 0,
+ };
+}
+
} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_manager.h b/src/core/hle/service/caps/caps_manager.h
index 8337c655c..f65eb12c1 100644
--- a/src/core/hle/service/caps/caps_manager.h
+++ b/src/core/hle/service/caps/caps_manager.h
@@ -37,7 +37,7 @@ namespace Service::Capture {
class AlbumManager {
public:
- explicit AlbumManager();
+ explicit AlbumManager(Core::System& system_);
~AlbumManager();
Result DeleteAlbumFile(const AlbumFileId& file_id);
@@ -45,6 +45,9 @@ public:
Result GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage,
u8 flags) const;
Result GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries,
+ ContentType contex_type, s64 start_posix_time, s64 end_posix_time,
+ u64 aruid) const;
+ Result GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries,
ContentType contex_type, AlbumFileDateTime start_date,
AlbumFileDateTime end_date, u64 aruid) const;
Result GetAutoSavingStorage(bool& out_is_autosaving) const;
@@ -65,8 +68,12 @@ private:
Result LoadImage(std::span<u8> out_image, const std::filesystem::path& path, int width,
int height, ScreenShotDecoderFlag flag) const;
+ AlbumFileDateTime ConvertToAlbumDateTime(u64 posix_time) const;
+
bool is_mounted{};
std::unordered_map<AlbumFileId, std::filesystem::path> album_files;
+
+ Core::System& system;
};
} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_types.h b/src/core/hle/service/caps/caps_types.h
index bf6061273..7fd357954 100644
--- a/src/core/hle/service/caps/caps_types.h
+++ b/src/core/hle/service/caps/caps_types.h
@@ -41,13 +41,13 @@ enum class ScreenShotDecoderFlag : u64 {
// This is nn::capsrv::AlbumFileDateTime
struct AlbumFileDateTime {
- u16 year{};
- u8 month{};
- u8 day{};
- u8 hour{};
- u8 minute{};
- u8 second{};
- u8 unique_id{};
+ s16 year{};
+ s8 month{};
+ s8 day{};
+ s8 hour{};
+ s8 minute{};
+ s8 second{};
+ s8 unique_id{};
friend constexpr bool operator==(const AlbumFileDateTime&, const AlbumFileDateTime&) = default;
friend constexpr bool operator>(const AlbumFileDateTime& a, const AlbumFileDateTime& b) {
diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp
index 260f25490..b6b33fb2f 100644
--- a/src/core/hle/service/caps/caps_u.cpp
+++ b/src/core/hle/service/caps/caps_u.cpp
@@ -50,22 +50,35 @@ void IAlbumApplicationService::SetShimLibraryVersion(HLERequestContext& ctx) {
void IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto pid{rp.Pop<s32>()};
- const auto content_type{rp.PopEnum<ContentType>()};
- const auto start_posix_time{rp.Pop<s64>()};
- const auto end_posix_time{rp.Pop<s64>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ ContentType content_type;
+ INSERT_PADDING_BYTES(7);
+ s64 start_posix_time;
+ s64 end_posix_time;
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_Capture,
- "(STUBBED) called. pid={}, content_type={}, start_posix_time={}, "
- "end_posix_time={}, applet_resource_user_id={}",
- pid, content_type, start_posix_time, end_posix_time, applet_resource_user_id);
+ "(STUBBED) called. content_type={}, start_posix_time={}, end_posix_time={}, "
+ "applet_resource_user_id={}",
+ parameters.content_type, parameters.start_posix_time, parameters.end_posix_time,
+ parameters.applet_resource_user_id);
- // TODO: Translate posix to DateTime
+ Result result = ResultSuccess;
+
+ if (result.IsSuccess()) {
+ result = manager->IsAlbumMounted(AlbumStorage::Sd);
+ }
std::vector<ApplicationAlbumFileEntry> entries;
- const Result result =
- manager->GetAlbumFileList(entries, content_type, {}, {}, applet_resource_user_id);
+ if (result.IsSuccess()) {
+ result = manager->GetAlbumFileList(entries, parameters.content_type,
+ parameters.start_posix_time, parameters.end_posix_time,
+ parameters.applet_resource_user_id);
+ }
if (!entries.empty()) {
ctx.WriteBuffer(entries);
@@ -78,19 +91,38 @@ void IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(HLERequestCo
void IAlbumApplicationService::GetAlbumFileList3AaeAruid(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto pid{rp.Pop<s32>()};
- const auto content_type{rp.PopEnum<ContentType>()};
- const auto start_date_time{rp.PopRaw<AlbumFileDateTime>()};
- const auto end_date_time{rp.PopRaw<AlbumFileDateTime>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ ContentType content_type;
+ INSERT_PADDING_BYTES(1);
+ AlbumFileDateTime start_date_time;
+ AlbumFileDateTime end_date_time;
+ INSERT_PADDING_BYTES(6);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_Capture,
- "(STUBBED) called. pid={}, content_type={}, applet_resource_user_id={}", pid,
- content_type, applet_resource_user_id);
+ "(STUBBED) called. content_type={}, start_date={}/{}/{}, "
+ "end_date={}/{}/{}, applet_resource_user_id={}",
+ parameters.content_type, parameters.start_date_time.year,
+ parameters.start_date_time.month, parameters.start_date_time.day,
+ parameters.end_date_time.year, parameters.end_date_time.month,
+ parameters.end_date_time.day, parameters.applet_resource_user_id);
- std::vector<ApplicationAlbumFileEntry> entries;
- const Result result = manager->GetAlbumFileList(entries, content_type, start_date_time,
- end_date_time, applet_resource_user_id);
+ Result result = ResultSuccess;
+
+ if (result.IsSuccess()) {
+ result = manager->IsAlbumMounted(AlbumStorage::Sd);
+ }
+
+ std::vector<ApplicationAlbumEntry> entries;
+ if (result.IsSuccess()) {
+ result =
+ manager->GetAlbumFileList(entries, parameters.content_type, parameters.start_date_time,
+ parameters.end_date_time, parameters.applet_resource_user_id);
+ }
if (!entries.empty()) {
ctx.WriteBuffer(entries);
diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp
index 4ed3f02e2..0090e8568 100644
--- a/src/core/hle/service/jit/jit_context.cpp
+++ b/src/core/hle/service/jit/jit_context.cpp
@@ -156,6 +156,8 @@ public:
bool LoadNRO(std::span<const u8> data) {
local_memory.clear();
+
+ relocbase = local_memory.size();
local_memory.insert(local_memory.end(), data.begin(), data.end());
if (FixupRelocations()) {
@@ -181,8 +183,8 @@ public:
// https://refspecs.linuxbase.org/elf/gabi4+/ch5.dynamic.html
// https://refspecs.linuxbase.org/elf/gabi4+/ch4.reloc.html
VAddr dynamic_offset{mod_offset + callbacks->MemoryRead32(mod_offset + 4)};
- VAddr rela_dyn = 0;
- size_t num_rela = 0;
+ VAddr rela_dyn = 0, relr_dyn = 0;
+ size_t num_rela = 0, num_relr = 0;
while (true) {
const auto dyn{callbacks->ReadMemory<Elf64_Dyn>(dynamic_offset)};
dynamic_offset += sizeof(Elf64_Dyn);
@@ -196,6 +198,12 @@ public:
if (dyn.d_tag == ElfDtRelasz) {
num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela);
}
+ if (dyn.d_tag == ElfDtRelr) {
+ relr_dyn = dyn.d_un.d_ptr;
+ }
+ if (dyn.d_tag == ElfDtRelrsz) {
+ num_relr = dyn.d_un.d_val / sizeof(Elf64_Relr);
+ }
}
for (size_t i = 0; i < num_rela; i++) {
@@ -207,6 +215,29 @@ public:
callbacks->MemoryWrite64(rela.r_offset, contents + rela.r_addend);
}
+ VAddr relr_where = 0;
+ for (size_t i = 0; i < num_relr; i++) {
+ const auto relr{callbacks->ReadMemory<Elf64_Relr>(relr_dyn + i * sizeof(Elf64_Relr))};
+ const auto incr{[&](VAddr where) {
+ callbacks->MemoryWrite64(where, callbacks->MemoryRead64(where) + relocbase);
+ }};
+
+ if ((relr & 1) == 0) {
+ // where pointer
+ relr_where = relocbase + relr;
+ incr(relr_where);
+ relr_where += sizeof(Elf64_Addr);
+ } else {
+ // bitmap
+ for (int bit = 1; bit < 64; bit++) {
+ if ((relr & (1ULL << bit)) != 0) {
+ incr(relr_where + i * sizeof(Elf64_Addr));
+ }
+ }
+ relr_where += 63 * sizeof(Elf64_Addr);
+ }
+ }
+
return true;
}
@@ -313,6 +344,7 @@ public:
Core::Memory::Memory& memory;
VAddr top_of_stack;
VAddr heap_pointer;
+ VAddr relocbase;
};
void DynarmicCallbacks64::CallSVC(u32 swi) {