summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/ldr/ldr.cpp52
1 files changed, 49 insertions, 3 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <memory> 5#include <memory>
6#include <fmt/format.h>
6 7
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/process.h"
7#include "core/hle/service/ldr/ldr.h" 10#include "core/hle/service/ldr/ldr.h"
8#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
12#include "core/loader/nro.h"
9 13
10namespace Service::LDR { 14namespace Service::LDR {
11 15
@@ -59,16 +63,58 @@ public:
59 explicit RelocatableObject() : ServiceFramework{"ldr:ro"} { 63 explicit RelocatableObject() : ServiceFramework{"ldr:ro"} {
60 // clang-format off 64 // clang-format off
61 static const FunctionInfo functions[] = { 65 static const FunctionInfo functions[] = {
62 {0, nullptr, "LoadNro"}, 66 {0, &RelocatableObject::LoadNro, "LoadNro"},
63 {1, nullptr, "UnloadNro"}, 67 {1, nullptr, "UnloadNro"},
64 {2, nullptr, "LoadNrr"}, 68 {2, &RelocatableObject::LoadNrr, "LoadNrr"},
65 {3, nullptr, "UnloadNrr"}, 69 {3, nullptr, "UnloadNrr"},
66 {4, nullptr, "Initialize"}, 70 {4, &RelocatableObject::Initialize, "Initialize"},
67 }; 71 };
68 // clang-format on 72 // clang-format on
69 73
70 RegisterHandlers(functions); 74 RegisterHandlers(functions);
71 } 75 }
76
77 void LoadNrr(Kernel::HLERequestContext& ctx) {
78 IPC::ResponseBuilder rb{ctx, 2};
79 rb.Push(RESULT_SUCCESS);
80 LOG_WARNING(Service_LDR, "(STUBBED) called");
81 }
82
83 void LoadNro(Kernel::HLERequestContext& ctx) {
84 IPC::RequestParser rp{ctx};
85 rp.Skip(2, false);
86 const VAddr nro_addr{rp.Pop<VAddr>()};
87 const u64 nro_size{rp.Pop<u64>()};
88 const VAddr bss_addr{rp.Pop<VAddr>()};
89 const u64 bss_size{rp.Pop<u64>()};
90
91 // Read NRO data from memory
92 std::vector<u8> nro_data(nro_size);
93 Memory::ReadBlock(nro_addr, nro_data.data(), nro_size);
94
95 // Load NRO as new executable module
96 const VAddr addr{*Core::CurrentProcess()->VMManager().FindFreeRegion(nro_size + bss_size)};
97 Loader::AppLoader_NRO::LoadNro(nro_data, fmt::format("nro-{:08x}", addr), addr);
98
99 // TODO(bunnei): This is an incomplete implementation. It was tested with Super Mario Party.
100 // It is currently missing:
101 // - Signature checks with LoadNRR
102 // - Checking if a module has already been loaded
103 // - Using/validating BSS, etc. params (these are used from NRO header instead)
104 // - Error checking
105 // - ...Probably other things
106
107 IPC::ResponseBuilder rb{ctx, 4};
108 rb.Push(RESULT_SUCCESS);
109 rb.Push(addr);
110 LOG_WARNING(Service_LDR, "(STUBBED) called");
111 }
112
113 void Initialize(Kernel::HLERequestContext& ctx) {
114 IPC::ResponseBuilder rb{ctx, 2};
115 rb.Push(RESULT_SUCCESS);
116 LOG_WARNING(Service_LDR, "(STUBBED) called");
117 }
72}; 118};
73 119
74void InstallInterfaces(SM::ServiceManager& sm) { 120void InstallInterfaces(SM::ServiceManager& sm) {