summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-05-26 11:40:41 -0400
committerGravatar Zach Hilman2019-05-26 11:40:46 -0400
commitb77fde7c5c1f63aad9d4f01ea625805661870f3e (patch)
tree1a69520beebaac50ecd19d4c54828f7b8a498dd0 /src/core
parentprepo: Save reports from PlayReport service (diff)
downloadyuzu-b77fde7c5c1f63aad9d4f01ea625805661870f3e.tar.gz
yuzu-b77fde7c5c1f63aad9d4f01ea625805661870f3e.tar.xz
yuzu-b77fde7c5c1f63aad9d4f01ea625805661870f3e.zip
loader: Move NSO module tracking to AppLoader
Also cleanup of general stuff
Diffstat (limited to 'src/core')
-rw-r--r--src/core/arm/arm_interface.cpp27
-rw-r--r--src/core/core.cpp11
-rw-r--r--src/core/core.h4
-rw-r--r--src/core/hle/service/am/applets/applets.cpp5
-rw-r--r--src/core/hle/service/am/applets/general_backend.h2
-rw-r--r--src/core/hle/service/prepo/prepo.cpp6
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp11
-rw-r--r--src/core/loader/deconstructed_rom_directory.h4
-rw-r--r--src/core/loader/loader.h6
-rw-r--r--src/core/loader/nax.cpp4
-rw-r--r--src/core/loader/nax.h2
-rw-r--r--src/core/loader/nca.cpp9
-rw-r--r--src/core/loader/nca.h2
-rw-r--r--src/core/loader/nso.cpp12
-rw-r--r--src/core/loader/nso.h5
-rw-r--r--src/core/loader/nsp.cpp4
-rw-r--r--src/core/loader/nsp.h2
-rw-r--r--src/core/loader/xci.cpp4
-rw-r--r--src/core/loader/xci.h2
-rw-r--r--src/core/reporter.cpp74
-rw-r--r--src/core/reporter.h9
21 files changed, 135 insertions, 70 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 2945fcff8..372612c9b 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -9,6 +9,7 @@
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/arm/arm_interface.h" 10#include "core/arm/arm_interface.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/loader/loader.h"
12#include "core/memory.h" 13#include "core/memory.h"
13 14
14namespace Core { 15namespace Core {
@@ -80,15 +81,17 @@ Symbols GetSymbols(VAddr text_offset) {
80 const auto value = Memory::Read64(dynamic_index + 0x8); 81 const auto value = Memory::Read64(dynamic_index + 0x8);
81 dynamic_index += 0x10; 82 dynamic_index += 0x10;
82 83
83 if (tag == ELF_DYNAMIC_TAG_NULL) 84 if (tag == ELF_DYNAMIC_TAG_NULL) {
84 break; 85 break;
86 }
85 87
86 if (tag == ELF_DYNAMIC_TAG_STRTAB) 88 if (tag == ELF_DYNAMIC_TAG_STRTAB) {
87 string_table_offset = value; 89 string_table_offset = value;
88 else if (tag == ELF_DYNAMIC_TAG_SYMTAB) 90 } else if (tag == ELF_DYNAMIC_TAG_SYMTAB) {
89 symbol_table_offset = value; 91 symbol_table_offset = value;
90 else if (tag == ELF_DYNAMIC_TAG_SYMENT) 92 } else if (tag == ELF_DYNAMIC_TAG_SYMENT) {
91 symbol_entry_size = value; 93 symbol_entry_size = value;
94 }
92 } 95 }
93 96
94 if (string_table_offset == 0 || symbol_table_offset == 0 || symbol_entry_size == 0) { 97 if (string_table_offset == 0 || symbol_table_offset == 0 || symbol_entry_size == 0) {
@@ -126,8 +129,10 @@ std::optional<std::string> GetSymbolName(const Symbols& symbols, VAddr func_addr
126 return func_address >= symbol.value && func_address < end_address; 129 return func_address >= symbol.value && func_address < end_address;
127 }); 130 });
128 131
129 if (iter == symbols.end()) 132 if (iter == symbols.end()) {
130 return std::nullopt; 133 return std::nullopt;
134 }
135
131 return iter->second; 136 return iter->second;
132} 137}
133 138
@@ -150,7 +155,12 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const {
150 fp = Memory::Read64(fp); 155 fp = Memory::Read64(fp);
151 } 156 }
152 157
153 const auto& modules{System::GetInstance().GetRegisteredNSOModules()}; 158 std::map<VAddr, std::string> modules;
159 auto& loader{System::GetInstance().GetAppLoader()};
160 if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) {
161 return {};
162 }
163
154 std::map<std::string, Symbols> symbols; 164 std::map<std::string, Symbols> symbols;
155 for (const auto& module : modules) { 165 for (const auto& module : modules) {
156 symbols.insert_or_assign(module.second, GetSymbols(module.first)); 166 symbols.insert_or_assign(module.second, GetSymbols(module.first));
@@ -158,7 +168,8 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const {
158 168
159 for (auto& entry : out) { 169 for (auto& entry : out) {
160 VAddr base = 0; 170 VAddr base = 0;
161 for (const auto& module : modules) { 171 for (auto iter = modules.rbegin(); iter != modules.rend(); ++iter) {
172 const auto& module{*iter};
162 if (entry.original_address >= module.first) { 173 if (entry.original_address >= module.first) {
163 entry.module = module.second; 174 entry.module = module.second;
164 base = module.first; 175 base = module.first;
@@ -191,7 +202,7 @@ void ARM_Interface::LogBacktrace() const {
191 LOG_ERROR(Core_ARM, "Backtrace, sp={:016X}, pc={:016X}", sp, pc); 202 LOG_ERROR(Core_ARM, "Backtrace, sp={:016X}, pc={:016X}", sp, pc);
192 LOG_ERROR(Core_ARM, "{:20}{:20}{:20}{:20}{}", "Module Name", "Address", "Original Address", 203 LOG_ERROR(Core_ARM, "{:20}{:20}{:20}{:20}{}", "Module Name", "Address", "Original Address",
193 "Offset", "Symbol"); 204 "Offset", "Symbol");
194 LOG_ERROR(Core_ARM, "{}", std::string(100, '-')); 205 LOG_ERROR(Core_ARM, "");
195 206
196 const auto backtrace = GetBacktrace(); 207 const auto backtrace = GetBacktrace();
197 for (const auto& entry : backtrace) { 208 for (const auto& entry : backtrace) {
diff --git a/src/core/core.cpp b/src/core/core.cpp
index db4c067df..ac9eeddbb 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -83,7 +83,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
83 return vfs->OpenFile(path, FileSys::Mode::Read); 83 return vfs->OpenFile(path, FileSys::Mode::Read);
84} 84}
85struct System::Impl { 85struct System::Impl {
86 explicit Impl(System& system) : kernel{system}, cpu_core_manager{system} {} 86 explicit Impl(System& system) : kernel{system}, cpu_core_manager{system}, reporter{system} {}
87 87
88 Cpu& CurrentCpuCore() { 88 Cpu& CurrentCpuCore() {
89 return cpu_core_manager.GetCurrentCore(); 89 return cpu_core_manager.GetCurrentCore();
@@ -271,7 +271,6 @@ struct System::Impl {
271 /// Telemetry session for this emulation session 271 /// Telemetry session for this emulation session
272 std::unique_ptr<Core::TelemetrySession> telemetry_session; 272 std::unique_ptr<Core::TelemetrySession> telemetry_session;
273 273
274 std::map<VAddr, std::string, std::greater<>> modules;
275 Reporter reporter; 274 Reporter reporter;
276 275
277 ResultStatus status = ResultStatus::Success; 276 ResultStatus status = ResultStatus::Success;
@@ -513,14 +512,6 @@ void System::ClearContentProvider(FileSys::ContentProviderUnionSlot slot) {
513 impl->content_provider->ClearSlot(slot); 512 impl->content_provider->ClearSlot(slot);
514} 513}
515 514
516void System::RegisterNSOModule(std::string name, VAddr start_address) {
517 impl->modules.insert_or_assign(start_address, name);
518}
519
520const std::map<VAddr, std::string, std::greater<>>& System::GetRegisteredNSOModules() const {
521 return impl->modules;
522}
523
524const Reporter& System::GetReporter() const { 515const Reporter& System::GetReporter() const {
525 return impl->reporter; 516 return impl->reporter;
526} 517}
diff --git a/src/core/core.h b/src/core/core.h
index 440cdbbf0..e033057aa 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -287,10 +287,6 @@ public:
287 287
288 void ClearContentProvider(FileSys::ContentProviderUnionSlot slot); 288 void ClearContentProvider(FileSys::ContentProviderUnionSlot slot);
289 289
290 void RegisterNSOModule(std::string name, VAddr start_address);
291
292 const std::map<VAddr, std::string, std::greater<>>& GetRegisteredNSOModules() const;
293
294 const Reporter& GetReporter() const; 290 const Reporter& GetReporter() const;
295 291
296private: 292private:
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 2a945bc7b..d8ad0079a 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -37,17 +37,18 @@ AppletDataBroker::~AppletDataBroker() = default;
37 37
38AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const { 38AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const {
39 std::vector<std::vector<u8>> out_normal; 39 std::vector<std::vector<u8>> out_normal;
40 std::vector<std::vector<u8>> out_interactive;
41 40
42 for (const auto& storage : in_channel) { 41 for (const auto& storage : in_channel) {
43 out_normal.push_back(storage->GetData()); 42 out_normal.push_back(storage->GetData());
44 } 43 }
45 44
45 std::vector<std::vector<u8>> out_interactive;
46
46 for (const auto& storage : in_interactive_channel) { 47 for (const auto& storage : in_interactive_channel) {
47 out_interactive.push_back(storage->GetData()); 48 out_interactive.push_back(storage->GetData());
48 } 49 }
49 50
50 return {out_normal, out_interactive}; 51 return {std::move(out_normal), std::move(out_interactive)};
51} 52}
52 53
53std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { 54std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h
index bc919a8dd..fb68a2543 100644
--- a/src/core/hle/service/am/applets/general_backend.h
+++ b/src/core/hle/service/am/applets/general_backend.h
@@ -34,7 +34,7 @@ private:
34 34
35class StubApplet final : public Applet { 35class StubApplet final : public Applet {
36public: 36public:
37 StubApplet(AppletId id); 37 explicit StubApplet(AppletId id);
38 ~StubApplet() override; 38 ~StubApplet() override;
39 39
40 void Initialize() override; 40 void Initialize() override;
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index 961b8882d..7e134f5c1 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -50,7 +50,7 @@ private:
50 void SaveReportWithUserOld(Kernel::HLERequestContext& ctx) { 50 void SaveReportWithUserOld(Kernel::HLERequestContext& ctx) {
51 IPC::RequestParser rp{ctx}; 51 IPC::RequestParser rp{ctx};
52 const auto user_id = rp.PopRaw<u128>(); 52 const auto user_id = rp.PopRaw<u128>();
53 const auto unk1 = rp.PopRaw<u64>(); 53 const auto process_id = rp.PopRaw<u64>();
54 54
55 const auto data1 = ctx.ReadBuffer(0); 55 const auto data1 = ctx.ReadBuffer(0);
56 const auto data2 = ctx.ReadBuffer(1); 56 const auto data2 = ctx.ReadBuffer(1);
@@ -58,10 +58,10 @@ private:
58 LOG_DEBUG( 58 LOG_DEBUG(
59 Service_PREPO, 59 Service_PREPO,
60 "called, user_id={:016X}{:016X}, unk1={:016X}, data1_size={:016X}, data2_size={:016X}", 60 "called, user_id={:016X}{:016X}, unk1={:016X}, data1_size={:016X}, data2_size={:016X}",
61 user_id[1], user_id[0], unk1, data1.size(), data2.size()); 61 user_id[1], user_id[0], process_id, data1.size(), data2.size());
62 62
63 const auto& reporter{Core::System::GetInstance().GetReporter()}; 63 const auto& reporter{Core::System::GetInstance().GetReporter()};
64 reporter.SavePlayReport(Core::CurrentProcess()->GetTitleID(), unk1, {data1, data2}, 64 reporter.SavePlayReport(Core::CurrentProcess()->GetTitleID(), process_id, {data1, data2},
65 user_id); 65 user_id);
66 66
67 IPC::ResponseBuilder rb{ctx, 2}; 67 IPC::ResponseBuilder rb{ctx, 2};
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 10b13fb1d..f9e88be2b 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -141,6 +141,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
141 const FileSys::PatchManager pm(metadata.GetTitleID()); 141 const FileSys::PatchManager pm(metadata.GetTitleID());
142 142
143 // Load NSO modules 143 // Load NSO modules
144 modules.clear();
144 const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); 145 const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
145 VAddr next_load_addr = base_address; 146 VAddr next_load_addr = base_address;
146 for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", 147 for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
@@ -159,6 +160,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
159 } 160 }
160 161
161 next_load_addr = *tentative_next_load_addr; 162 next_load_addr = *tentative_next_load_addr;
163 modules.insert_or_assign(load_addr, module);
162 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); 164 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
163 // Register module with GDBStub 165 // Register module with GDBStub
164 GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); 166 GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
@@ -212,4 +214,13 @@ bool AppLoader_DeconstructedRomDirectory::IsRomFSUpdatable() const {
212 return false; 214 return false;
213} 215}
214 216
217ResultStatus AppLoader_DeconstructedRomDirectory::ReadNSOModules(Modules& modules) {
218 if (!is_loaded) {
219 return ResultStatus::ErrorNotInitialized;
220 }
221
222 modules = this->modules;
223 return ResultStatus::Success;
224}
225
215} // namespace Loader 226} // namespace Loader
diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h
index 1a65c16a4..1c0a354a4 100644
--- a/src/core/loader/deconstructed_rom_directory.h
+++ b/src/core/loader/deconstructed_rom_directory.h
@@ -45,6 +45,8 @@ public:
45 ResultStatus ReadTitle(std::string& title) override; 45 ResultStatus ReadTitle(std::string& title) override;
46 bool IsRomFSUpdatable() const override; 46 bool IsRomFSUpdatable() const override;
47 47
48 ResultStatus ReadNSOModules(Modules& modules) override;
49
48private: 50private:
49 FileSys::ProgramMetadata metadata; 51 FileSys::ProgramMetadata metadata;
50 FileSys::VirtualFile romfs; 52 FileSys::VirtualFile romfs;
@@ -54,6 +56,8 @@ private:
54 std::string name; 56 std::string name;
55 u64 title_id{}; 57 u64 title_id{};
56 bool override_update; 58 bool override_update;
59
60 Modules modules;
57}; 61};
58 62
59} // namespace Loader 63} // namespace Loader
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index f7846db52..d6372c559 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -278,6 +278,12 @@ public:
278 return ResultStatus::ErrorNotImplemented; 278 return ResultStatus::ErrorNotImplemented;
279 } 279 }
280 280
281 using Modules = std::map<VAddr, std::string>;
282
283 virtual ResultStatus ReadNSOModules(Modules& modules) {
284 return ResultStatus::ErrorNotImplemented;
285 }
286
281protected: 287protected:
282 FileSys::VirtualFile file; 288 FileSys::VirtualFile file;
283 bool is_loaded = false; 289 bool is_loaded = false;
diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp
index 34efef09a..a152981a0 100644
--- a/src/core/loader/nax.cpp
+++ b/src/core/loader/nax.cpp
@@ -94,4 +94,8 @@ ResultStatus AppLoader_NAX::ReadLogo(std::vector<u8>& buffer) {
94 return nca_loader->ReadLogo(buffer); 94 return nca_loader->ReadLogo(buffer);
95} 95}
96 96
97ResultStatus AppLoader_NAX::ReadNSOModules(Modules& modules) {
98 return nca_loader->ReadNSOModules(modules);
99}
100
97} // namespace Loader 101} // namespace Loader
diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h
index 00f1659c1..eaec9bf58 100644
--- a/src/core/loader/nax.h
+++ b/src/core/loader/nax.h
@@ -42,6 +42,8 @@ public:
42 ResultStatus ReadBanner(std::vector<u8>& buffer) override; 42 ResultStatus ReadBanner(std::vector<u8>& buffer) override;
43 ResultStatus ReadLogo(std::vector<u8>& buffer) override; 43 ResultStatus ReadLogo(std::vector<u8>& buffer) override;
44 44
45 ResultStatus ReadNSOModules(Modules& modules) override;
46
45private: 47private:
46 std::unique_ptr<FileSys::NAX> nax; 48 std::unique_ptr<FileSys::NAX> nax;
47 std::unique_ptr<AppLoader_NCA> nca_loader; 49 std::unique_ptr<AppLoader_NCA> nca_loader;
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index b3f8f1083..0f65fb637 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -105,4 +105,13 @@ ResultStatus AppLoader_NCA::ReadLogo(std::vector<u8>& buffer) {
105 buffer = logo->GetFile("NintendoLogo.png")->ReadAllBytes(); 105 buffer = logo->GetFile("NintendoLogo.png")->ReadAllBytes();
106 return ResultStatus::Success; 106 return ResultStatus::Success;
107} 107}
108
109ResultStatus AppLoader_NCA::ReadNSOModules(Modules& modules) {
110 if (directory_loader == nullptr) {
111 return ResultStatus::ErrorNotInitialized;
112 }
113
114 return directory_loader->ReadNSOModules(modules);
115}
116
108} // namespace Loader 117} // namespace Loader
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h
index 94f0ed677..e47dc0e47 100644
--- a/src/core/loader/nca.h
+++ b/src/core/loader/nca.h
@@ -42,6 +42,8 @@ public:
42 ResultStatus ReadBanner(std::vector<u8>& buffer) override; 42 ResultStatus ReadBanner(std::vector<u8>& buffer) override;
43 ResultStatus ReadLogo(std::vector<u8>& buffer) override; 43 ResultStatus ReadLogo(std::vector<u8>& buffer) override;
44 44
45 ResultStatus ReadNSOModules(Modules& modules) override;
46
45private: 47private:
46 std::unique_ptr<FileSys::NCA> nca; 48 std::unique_ptr<FileSys::NCA> nca;
47 std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader; 49 std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader;
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 7beeaaff3..e0d6ab473 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -164,9 +164,6 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
164 // Register module with GDBStub 164 // Register module with GDBStub
165 GDBStub::RegisterModule(file.GetName(), load_base, load_base); 165 GDBStub::RegisterModule(file.GetName(), load_base, load_base);
166 166
167 // Register module for ARMInterface with System
168 Core::System::GetInstance().RegisterNSOModule(file.GetName(), load_base);
169
170 return load_base + image_size; 167 return load_base + image_size;
171} 168}
172 169
@@ -175,11 +172,15 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::Process& process) {
175 return {ResultStatus::ErrorAlreadyLoaded, {}}; 172 return {ResultStatus::ErrorAlreadyLoaded, {}};
176 } 173 }
177 174
175 modules.clear();
176
178 // Load module 177 // Load module
179 const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); 178 const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
180 if (!LoadModule(process, *file, base_address, true)) { 179 if (!LoadModule(process, *file, base_address, true)) {
181 return {ResultStatus::ErrorLoadingNSO, {}}; 180 return {ResultStatus::ErrorLoadingNSO, {}};
182 } 181 }
182
183 modules.insert_or_assign(base_address, file->GetName());
183 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address); 184 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address);
184 185
185 is_loaded = true; 186 is_loaded = true;
@@ -187,4 +188,9 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::Process& process) {
187 LoadParameters{Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE}}; 188 LoadParameters{Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE}};
188} 189}
189 190
191ResultStatus AppLoader_NSO::ReadNSOModules(Modules& modules) {
192 modules = this->modules;
193 return ResultStatus::Success;
194}
195
190} // namespace Loader 196} // namespace Loader
diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h
index fdce9191c..58cbe162d 100644
--- a/src/core/loader/nso.h
+++ b/src/core/loader/nso.h
@@ -85,6 +85,11 @@ public:
85 std::optional<FileSys::PatchManager> pm = {}); 85 std::optional<FileSys::PatchManager> pm = {});
86 86
87 LoadResult Load(Kernel::Process& process) override; 87 LoadResult Load(Kernel::Process& process) override;
88
89 ResultStatus ReadNSOModules(Modules& modules) override;
90
91private:
92 Modules modules;
88}; 93};
89 94
90} // namespace Loader 95} // namespace Loader
diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp
index ad56bbb38..3a22ec2c6 100644
--- a/src/core/loader/nsp.cpp
+++ b/src/core/loader/nsp.cpp
@@ -183,4 +183,8 @@ ResultStatus AppLoader_NSP::ReadLogo(std::vector<u8>& buffer) {
183 return secondary_loader->ReadLogo(buffer); 183 return secondary_loader->ReadLogo(buffer);
184} 184}
185 185
186ResultStatus AppLoader_NSP::ReadNSOModules(Modules& modules) {
187 return secondary_loader->ReadNSOModules(modules);
188}
189
186} // namespace Loader 190} // namespace Loader
diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h
index 85e870bdf..868b028d3 100644
--- a/src/core/loader/nsp.h
+++ b/src/core/loader/nsp.h
@@ -49,6 +49,8 @@ public:
49 ResultStatus ReadBanner(std::vector<u8>& buffer) override; 49 ResultStatus ReadBanner(std::vector<u8>& buffer) override;
50 ResultStatus ReadLogo(std::vector<u8>& buffer) override; 50 ResultStatus ReadLogo(std::vector<u8>& buffer) override;
51 51
52 ResultStatus ReadNSOModules(Modules& modules) override;
53
52private: 54private:
53 std::unique_ptr<FileSys::NSP> nsp; 55 std::unique_ptr<FileSys::NSP> nsp;
54 std::unique_ptr<AppLoader> secondary_loader; 56 std::unique_ptr<AppLoader> secondary_loader;
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
index 1e285a053..a5c4d3688 100644
--- a/src/core/loader/xci.cpp
+++ b/src/core/loader/xci.cpp
@@ -149,4 +149,8 @@ ResultStatus AppLoader_XCI::ReadLogo(std::vector<u8>& buffer) {
149 return nca_loader->ReadLogo(buffer); 149 return nca_loader->ReadLogo(buffer);
150} 150}
151 151
152ResultStatus AppLoader_XCI::ReadNSOModules(Modules& modules) {
153 return nca_loader->ReadNSOModules(modules);
154}
155
152} // namespace Loader 156} // namespace Loader
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h
index ae7145b14..618ae2f47 100644
--- a/src/core/loader/xci.h
+++ b/src/core/loader/xci.h
@@ -49,6 +49,8 @@ public:
49 ResultStatus ReadBanner(std::vector<u8>& buffer) override; 49 ResultStatus ReadBanner(std::vector<u8>& buffer) override;
50 ResultStatus ReadLogo(std::vector<u8>& buffer) override; 50 ResultStatus ReadLogo(std::vector<u8>& buffer) override;
51 51
52 ResultStatus ReadNSOModules(Modules& modules) override;
53
52private: 54private:
53 std::unique_ptr<FileSys::XCI> xci; 55 std::unique_ptr<FileSys::XCI> xci;
54 std::unique_ptr<AppLoader_NCA> nca_loader; 56 std::unique_ptr<AppLoader_NCA> nca_loader;
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index 95dcfffb5..8fe621aa0 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -11,6 +11,7 @@
11#include "core/core.h" 11#include "core/core.h"
12#include "core/hle/kernel/hle_ipc.h" 12#include "core/hle/kernel/hle_ipc.h"
13#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
14#include "core/hle/result.h"
14#include "core/reporter.h" 15#include "core/reporter.h"
15#include "core/settings.h" 16#include "core/settings.h"
16#include "fmt/time.h" 17#include "fmt/time.h"
@@ -30,12 +31,12 @@ std::string GetTimestamp() {
30using namespace nlohmann; 31using namespace nlohmann;
31 32
32void SaveToFile(const json& json, const std::string& filename) { 33void SaveToFile(const json& json, const std::string& filename) {
33 FileUtil::CreateFullPath(filename); 34 if (!FileUtil::CreateFullPath(filename))
35 LOG_ERROR(Core, "Failed to create path for '{}' to save report!", filename);
36
34 std::ofstream file( 37 std::ofstream file(
35 FileUtil::SanitizePath(filename, FileUtil::DirectorySeparator::PlatformDefault)); 38 FileUtil::SanitizePath(filename, FileUtil::DirectorySeparator::PlatformDefault));
36 file << std::setw(4) << json << std::endl; 39 file << std::setw(4) << json << std::endl;
37 file.flush();
38 file.close();
39} 40}
40 41
41json GetYuzuVersionData() { 42json GetYuzuVersionData() {
@@ -62,7 +63,7 @@ json GetReportCommonData(u64 title_id, ResultCode result, const std::string& tim
62 }; 63 };
63 if (user_id.has_value()) 64 if (user_id.has_value())
64 out["user_id"] = fmt::format("{:016X}{:016X}", (*user_id)[1], (*user_id)[0]); 65 out["user_id"] = fmt::format("{:016X}{:016X}", (*user_id)[1], (*user_id)[0]);
65 return std::move(out); 66 return out;
66} 67}
67 68
68json GetProcessorStateData(const std::string& architecture, u64 entry_point, u64 sp, u64 pc, 69json GetProcessorStateData(const std::string& architecture, u64 entry_point, u64 sp, u64 pc,
@@ -91,13 +92,13 @@ json GetProcessorStateData(const std::string& architecture, u64 entry_point, u64
91 out["backtrace"] = std::move(backtrace_out); 92 out["backtrace"] = std::move(backtrace_out);
92 } 93 }
93 94
94 return std::move(out); 95 return out;
95} 96}
96 97
97json GetProcessorStateDataAuto() { 98json GetProcessorStateDataAuto(Core::System& system) {
98 const auto* process{Core::CurrentProcess()}; 99 const auto* process{system.CurrentProcess()};
99 const auto& vm_manager{process->VMManager()}; 100 const auto& vm_manager{process->VMManager()};
100 auto& arm{Core::CurrentArmInterface()}; 101 auto& arm{system.CurrentArmInterface()};
101 102
102 Core::ARM_Interface::ThreadContext context{}; 103 Core::ARM_Interface::ThreadContext context{};
103 arm.SaveContext(context); 104 arm.SaveContext(context);
@@ -107,9 +108,9 @@ json GetProcessorStateDataAuto() {
107 context.pstate, context.cpu_registers); 108 context.pstate, context.cpu_registers);
108} 109}
109 110
110json GetBacktraceData() { 111json GetBacktraceData(Core::System& system) {
111 auto out = json::array(); 112 auto out = json::array();
112 const auto& backtrace{Core::CurrentArmInterface().GetBacktrace()}; 113 const auto& backtrace{system.CurrentArmInterface().GetBacktrace()};
113 for (const auto& entry : backtrace) { 114 for (const auto& entry : backtrace) {
114 out.push_back({ 115 out.push_back({
115 {"module", entry.module}, 116 {"module", entry.module},
@@ -120,18 +121,18 @@ json GetBacktraceData() {
120 }); 121 });
121 } 122 }
122 123
123 return std::move(out); 124 return out;
124} 125}
125 126
126json GetFullDataAuto(const std::string& timestamp, u64 title_id) { 127json GetFullDataAuto(const std::string& timestamp, u64 title_id, Core::System& system) {
127 json out; 128 json out;
128 129
129 out["yuzu_version"] = GetYuzuVersionData(); 130 out["yuzu_version"] = GetYuzuVersionData();
130 out["report_common"] = GetReportCommonData(title_id, RESULT_SUCCESS, timestamp); 131 out["report_common"] = GetReportCommonData(title_id, RESULT_SUCCESS, timestamp);
131 out["processor_state"] = GetProcessorStateDataAuto(); 132 out["processor_state"] = GetProcessorStateDataAuto(system);
132 out["backtrace"] = GetBacktraceData(); 133 out["backtrace"] = GetBacktraceData(system);
133 134
134 return std::move(out); 135 return out;
135} 136}
136 137
137template <bool read_value, typename DescriptorType> 138template <bool read_value, typename DescriptorType>
@@ -152,7 +153,7 @@ json GetHLEBufferDescriptorData(const std::vector<DescriptorType>& buffer) {
152 buffer_out.push_back(std::move(entry)); 153 buffer_out.push_back(std::move(entry));
153 } 154 }
154 155
155 return std::move(buffer_out); 156 return buffer_out;
156} 157}
157 158
158json GetHLERequestContextData(Kernel::HLERequestContext& ctx) { 159json GetHLERequestContextData(Kernel::HLERequestContext& ctx) {
@@ -177,7 +178,7 @@ json GetHLERequestContextData(Kernel::HLERequestContext& ctx) {
177 178
178namespace Core { 179namespace Core {
179 180
180Reporter::Reporter() = default; 181Reporter::Reporter(Core::System& system) : system(system) {}
181 182
182Reporter::~Reporter() = default; 183Reporter::~Reporter() = default;
183 184
@@ -189,7 +190,7 @@ void Reporter::SaveCrashReport(u64 title_id, ResultCode result, u64 set_flags, u
189 if (!IsReportingEnabled()) 190 if (!IsReportingEnabled())
190 return; 191 return;
191 192
192 const auto timestamp{GetTimestamp()}; 193 const auto timestamp = GetTimestamp();
193 json out; 194 json out;
194 195
195 out["yuzu_version"] = GetYuzuVersionData(); 196 out["yuzu_version"] = GetYuzuVersionData();
@@ -214,9 +215,9 @@ void Reporter::SaveSvcBreakReport(u32 type, bool signal_debugger, u64 info1, u64
214 if (!IsReportingEnabled()) 215 if (!IsReportingEnabled())
215 return; 216 return;
216 217
217 const auto timestamp{GetTimestamp()}; 218 const auto timestamp = GetTimestamp();
218 const auto title_id{Core::CurrentProcess()->GetTitleID()}; 219 const auto title_id = system.CurrentProcess()->GetTitleID();
219 auto out = GetFullDataAuto(timestamp, title_id); 220 auto out = GetFullDataAuto(timestamp, title_id, system);
220 221
221 auto break_out = json{ 222 auto break_out = json{
222 {"type", fmt::format("{:08X}", type)}, 223 {"type", fmt::format("{:08X}", type)},
@@ -240,9 +241,9 @@ void Reporter::SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u
240 if (!IsReportingEnabled()) 241 if (!IsReportingEnabled())
241 return; 242 return;
242 243
243 const auto timestamp{GetTimestamp()}; 244 const auto timestamp = GetTimestamp();
244 const auto title_id{Core::CurrentProcess()->GetTitleID()}; 245 const auto title_id = system.CurrentProcess()->GetTitleID();
245 auto out = GetFullDataAuto(timestamp, title_id); 246 auto out = GetFullDataAuto(timestamp, title_id, system);
246 247
247 auto function_out = GetHLERequestContextData(ctx); 248 auto function_out = GetHLERequestContextData(ctx);
248 function_out["command_id"] = command_id; 249 function_out["command_id"] = command_id;
@@ -261,9 +262,9 @@ void Reporter::SaveUnimplementedAppletReport(
261 if (!IsReportingEnabled()) 262 if (!IsReportingEnabled())
262 return; 263 return;
263 264
264 const auto timestamp{GetTimestamp()}; 265 const auto timestamp = GetTimestamp();
265 const auto title_id{Core::CurrentProcess()->GetTitleID()}; 266 const auto title_id = system.CurrentProcess()->GetTitleID();
266 auto out = GetFullDataAuto(timestamp, title_id); 267 auto out = GetFullDataAuto(timestamp, title_id, system);
267 268
268 out["applet_common_args"] = { 269 out["applet_common_args"] = {
269 {"applet_id", fmt::format("{:02X}", applet_id)}, 270 {"applet_id", fmt::format("{:02X}", applet_id)},
@@ -290,12 +291,12 @@ void Reporter::SaveUnimplementedAppletReport(
290 SaveToFile(std::move(out), GetPath("unimpl_applet_report", title_id, timestamp)); 291 SaveToFile(std::move(out), GetPath("unimpl_applet_report", title_id, timestamp));
291} 292}
292 293
293void Reporter::SavePlayReport(u64 title_id, u64 unk1, std::vector<std::vector<u8>> data, 294void Reporter::SavePlayReport(u64 title_id, u64 process_id, std::vector<std::vector<u8>> data,
294 std::optional<u128> user_id) const { 295 std::optional<u128> user_id) const {
295 if (!IsReportingEnabled()) 296 if (!IsReportingEnabled())
296 return; 297 return;
297 298
298 const auto timestamp{GetTimestamp()}; 299 const auto timestamp = GetTimestamp();
299 json out; 300 json out;
300 301
301 out["yuzu_version"] = GetYuzuVersionData(); 302 out["yuzu_version"] = GetYuzuVersionData();
@@ -306,7 +307,7 @@ void Reporter::SavePlayReport(u64 title_id, u64 unk1, std::vector<std::vector<u8
306 data_out.push_back(Common::HexVectorToString(d)); 307 data_out.push_back(Common::HexVectorToString(d));
307 } 308 }
308 309
309 out["play_report_unk1"] = fmt::format("{:016X}", unk1); 310 out["play_report_process_id"] = fmt::format("{:016X}", process_id);
310 out["play_report_data"] = std::move(data_out); 311 out["play_report_data"] = std::move(data_out);
311 312
312 SaveToFile(std::move(out), GetPath("play_report", title_id, timestamp)); 313 SaveToFile(std::move(out), GetPath("play_report", title_id, timestamp));
@@ -318,13 +319,13 @@ void Reporter::SaveErrorReport(u64 title_id, ResultCode result,
318 if (!IsReportingEnabled()) 319 if (!IsReportingEnabled())
319 return; 320 return;
320 321
321 const auto timestamp{GetTimestamp()}; 322 const auto timestamp = GetTimestamp();
322 json out; 323 json out;
323 324
324 out["yuzu_version"] = GetYuzuVersionData(); 325 out["yuzu_version"] = GetYuzuVersionData();
325 out["report_common"] = GetReportCommonData(title_id, result, timestamp); 326 out["report_common"] = GetReportCommonData(title_id, result, timestamp);
326 out["processor_state"] = GetProcessorStateDataAuto(); 327 out["processor_state"] = GetProcessorStateDataAuto(system);
327 out["backtrace"] = GetBacktraceData(); 328 out["backtrace"] = GetBacktraceData(system);
328 329
329 out["error_custom_text"] = { 330 out["error_custom_text"] = {
330 {"main", *custom_text_main}, 331 {"main", *custom_text_main},
@@ -338,10 +339,11 @@ void Reporter::SaveUserReport() const {
338 if (!IsReportingEnabled()) 339 if (!IsReportingEnabled())
339 return; 340 return;
340 341
341 const auto timestamp{GetTimestamp()}; 342 const auto timestamp = GetTimestamp();
342 const auto title_id{Core::CurrentProcess()->GetTitleID()}; 343 const auto title_id = system.CurrentProcess()->GetTitleID();
343 344
344 SaveToFile(GetFullDataAuto(timestamp, title_id), GetPath("user_report", title_id, timestamp)); 345 SaveToFile(GetFullDataAuto(timestamp, title_id, system),
346 GetPath("user_report", title_id, timestamp));
345} 347}
346 348
347bool Reporter::IsReportingEnabled() const { 349bool Reporter::IsReportingEnabled() const {
diff --git a/src/core/reporter.h b/src/core/reporter.h
index 2f798ee16..3de19c0f7 100644
--- a/src/core/reporter.h
+++ b/src/core/reporter.h
@@ -7,7 +7,8 @@
7#include <optional> 7#include <optional>
8#include <vector> 8#include <vector>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/result.h" 10
11union ResultCode;
11 12
12namespace Kernel { 13namespace Kernel {
13class HLERequestContext; 14class HLERequestContext;
@@ -17,7 +18,7 @@ namespace Core {
17 18
18class Reporter { 19class Reporter {
19public: 20public:
20 Reporter(); 21 explicit Reporter(Core::System& system);
21 ~Reporter(); 22 ~Reporter();
22 23
23 void SaveCrashReport(u64 title_id, ResultCode result, u64 set_flags, u64 entry_point, u64 sp, 24 void SaveCrashReport(u64 title_id, ResultCode result, u64 set_flags, u64 entry_point, u64 sp,
@@ -37,7 +38,7 @@ public:
37 std::vector<std::vector<u8>> normal_channel, 38 std::vector<std::vector<u8>> normal_channel,
38 std::vector<std::vector<u8>> interactive_channel) const; 39 std::vector<std::vector<u8>> interactive_channel) const;
39 40
40 void SavePlayReport(u64 title_id, u64 unk1, std::vector<std::vector<u8>> data, 41 void SavePlayReport(u64 title_id, u64 process_id, std::vector<std::vector<u8>> data,
41 std::optional<u128> user_id = {}) const; 42 std::optional<u128> user_id = {}) const;
42 43
43 void SaveErrorReport(u64 title_id, ResultCode result, 44 void SaveErrorReport(u64 title_id, ResultCode result,
@@ -48,6 +49,8 @@ public:
48 49
49private: 50private:
50 bool IsReportingEnabled() const; 51 bool IsReportingEnabled() const;
52
53 Core::System& system;
51}; 54};
52 55
53} // namespace Core 56} // namespace Core