aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/ldr/ldr.cpp52
-rw-r--r--src/core/hle/service/nfp/nfp.cpp6
-rw-r--r--src/core/hle/service/nfp/nfp.h2
3 files changed, 54 insertions, 6 deletions
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index ec32faf15..d607d985e 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -3,9 +3,13 @@
// Refer to the license.txt file included.
#include <memory>
+#include <fmt/format.h>
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/process.h"
#include "core/hle/service/ldr/ldr.h"
#include "core/hle/service/service.h"
+#include "core/loader/nro.h"
namespace Service::LDR {
@@ -59,16 +63,58 @@ public:
explicit RelocatableObject() : ServiceFramework{"ldr:ro"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "LoadNro"},
+ {0, &RelocatableObject::LoadNro, "LoadNro"},
{1, nullptr, "UnloadNro"},
- {2, nullptr, "LoadNrr"},
+ {2, &RelocatableObject::LoadNrr, "LoadNrr"},
{3, nullptr, "UnloadNrr"},
- {4, nullptr, "Initialize"},
+ {4, &RelocatableObject::Initialize, "Initialize"},
};
// clang-format on
RegisterHandlers(functions);
}
+
+ void LoadNrr(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ LOG_WARNING(Service_LDR, "(STUBBED) called");
+ }
+
+ void LoadNro(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ rp.Skip(2, false);
+ const VAddr nro_addr{rp.Pop<VAddr>()};
+ const u64 nro_size{rp.Pop<u64>()};
+ const VAddr bss_addr{rp.Pop<VAddr>()};
+ const u64 bss_size{rp.Pop<u64>()};
+
+ // Read NRO data from memory
+ std::vector<u8> nro_data(nro_size);
+ Memory::ReadBlock(nro_addr, nro_data.data(), nro_size);
+
+ // Load NRO as new executable module
+ const VAddr addr{*Core::CurrentProcess()->VMManager().FindFreeRegion(nro_size + bss_size)};
+ Loader::AppLoader_NRO::LoadNro(nro_data, fmt::format("nro-{:08x}", addr), addr);
+
+ // TODO(bunnei): This is an incomplete implementation. It was tested with Super Mario Party.
+ // It is currently missing:
+ // - Signature checks with LoadNRR
+ // - Checking if a module has already been loaded
+ // - Using/validating BSS, etc. params (these are used from NRO header instead)
+ // - Error checking
+ // - ...Probably other things
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(addr);
+ LOG_WARNING(Service_LDR, "(STUBBED) called");
+ }
+
+ void Initialize(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ LOG_WARNING(Service_LDR, "(STUBBED) called");
+ }
};
void InstallInterfaces(SM::ServiceManager& sm) {
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index 9a4eb9301..c1af878fe 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -328,13 +328,15 @@ void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IUser>(*this);
}
-void Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
+bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
if (buffer.size() < sizeof(AmiiboFile)) {
- return; // Failed to load file
+ return false;
}
+
std::memcpy(&amiibo, buffer.data(), sizeof(amiibo));
nfc_tag_load->Signal();
+ return true;
}
const Kernel::SharedPtr<Kernel::Event>& Module::Interface::GetNFCEvent() const {
return nfc_tag_load;
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
index 46370dedd..5c0ae8a54 100644
--- a/src/core/hle/service/nfp/nfp.h
+++ b/src/core/hle/service/nfp/nfp.h
@@ -32,7 +32,7 @@ public:
static_assert(sizeof(AmiiboFile) == 0x94, "AmiiboFile is an invalid size");
void CreateUserInterface(Kernel::HLERequestContext& ctx);
- void LoadAmiibo(const std::vector<u8>& buffer);
+ bool LoadAmiibo(const std::vector<u8>& buffer);
const Kernel::SharedPtr<Kernel::Event>& GetNFCEvent() const;
const AmiiboFile& GetAmiiboBuffer() const;