MCPcopy Create free account
hub / github.com/amwatson/CitraVR / LoadExec

Method LoadExec

src/core/loader/ncch.cpp:98–216  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

96}
97
98ResultStatus AppLoader_NCCH::LoadExec(std::shared_ptr<Kernel::Process>& process) {
99 using Kernel::CodeSet;
100
101 if (!is_loaded)
102 return ResultStatus::ErrorNotLoaded;
103
104 std::vector<u8> code;
105 u64_le program_id;
106 if (ResultStatus::Success == ReadCode(code) &&
107 ResultStatus::Success == ReadProgramId(program_id)) {
108 if (IsGbaVirtualConsole(code)) {
109 LOG_ERROR(Loader, "Encountered unsupported GBA Virtual Console code section.");
110 return ResultStatus::ErrorGbaTitle;
111 }
112
113 std::string process_name = Common::StringFromFixedZeroTerminatedBuffer(
114 (const char*)overlay_ncch->exheader_header.codeset_info.name, 8);
115
116 std::shared_ptr<CodeSet> codeset = system.Kernel().CreateCodeSet(process_name, program_id);
117
118 codeset->CodeSegment().offset = 0;
119 codeset->CodeSegment().addr = overlay_ncch->exheader_header.codeset_info.text.address;
120 codeset->CodeSegment().size =
121 overlay_ncch->exheader_header.codeset_info.text.num_max_pages * Memory::CITRA_PAGE_SIZE;
122
123 codeset->RODataSegment().offset =
124 codeset->CodeSegment().offset + codeset->CodeSegment().size;
125 codeset->RODataSegment().addr = overlay_ncch->exheader_header.codeset_info.ro.address;
126 codeset->RODataSegment().size =
127 overlay_ncch->exheader_header.codeset_info.ro.num_max_pages * Memory::CITRA_PAGE_SIZE;
128
129 // TODO(yuriks): Not sure if the bss size is added to the page-aligned .data size or just
130 // to the regular size. Playing it safe for now.
131 u32 bss_page_size = (overlay_ncch->exheader_header.codeset_info.bss_size + 0xFFF) & ~0xFFF;
132 code.resize(code.size() + bss_page_size, 0);
133
134 codeset->DataSegment().offset =
135 codeset->RODataSegment().offset + codeset->RODataSegment().size;
136 codeset->DataSegment().addr = overlay_ncch->exheader_header.codeset_info.data.address;
137 codeset->DataSegment().size =
138 overlay_ncch->exheader_header.codeset_info.data.num_max_pages *
139 Memory::CITRA_PAGE_SIZE +
140 bss_page_size;
141
142 // Apply patches now that the entire codeset (including .bss) has been allocated
143 const ResultStatus patch_result = overlay_ncch->ApplyCodePatch(code);
144 if (patch_result != ResultStatus::Success && patch_result != ResultStatus::ErrorNotUsed)
145 return patch_result;
146
147 codeset->entrypoint = codeset->CodeSegment().addr;
148 codeset->memory = std::move(code);
149
150 process = system.Kernel().CreateProcess(std::move(codeset));
151
152 // Attach a resource limit to the process based on the resource limit category
153 const auto category = static_cast<Kernel::ResourceLimitCategory>(
154 overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category);
155 process->resource_limit = system.Kernel().ResourceLimit().GetForCategory(category);

Callers

nothing calls this directly

Calls 15

beginFunction · 0.85
CreateCodeSetMethod · 0.80
ApplyCodePatchMethod · 0.80
CreateProcessMethod · 0.80
GetForCategoryMethod · 0.80
ResourceLimitMethod · 0.80
ValueMethod · 0.80
GetValueMethod · 0.80
SetLimitValueMethod · 0.80
ParseKernelCapsMethod · 0.80
ServiceManagerMethod · 0.80

Tested by

no test coverage detected