mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
Loader: Start work on LoadNRR, Add AutoCloseMap
This commit is contained in:
parent
b34b9ba0e4
commit
1d73bd0a12
5 changed files with 105 additions and 26 deletions
|
@ -26,3 +26,46 @@ class MapUtils {
|
||||||
static Result MapCodeMemoryForProcessModern(Handle process_h, u64 base_address, u64 size, u64 *out_code_memory_address);
|
static Result MapCodeMemoryForProcessModern(Handle process_h, u64 base_address, u64 size, u64 *out_code_memory_address);
|
||||||
static Result MapCodeMemoryForProcess(Handle process_h, bool is_64_bit_address_space, u64 base_address, u64 size, u64 *out_code_memory_address);
|
static Result MapCodeMemoryForProcess(Handle process_h, bool is_64_bit_address_space, u64 base_address, u64 size, u64 *out_code_memory_address);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AutoCloseMap {
|
||||||
|
private:
|
||||||
|
void *mapped_address;
|
||||||
|
u64 base_address;
|
||||||
|
u64 size;
|
||||||
|
Handle process_handle;
|
||||||
|
public:
|
||||||
|
AutoCloseMap() : mapped_address(0), base_address(0), size(0), process_handle(0) { };
|
||||||
|
~AutoCloseMap() {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *GetMappedAddress() {
|
||||||
|
return this->mapped_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Open(Handle process_h, u64 address, u64 size) {
|
||||||
|
Result rc;
|
||||||
|
u64 try_address;
|
||||||
|
if (R_FAILED(rc = MapUtils::LocateSpaceForMap(&try_address, size))) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_FAILED((rc = svcMapProcessMemory((void *)try_address, process_h, try_address, size)))) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mapped_address = (void *)try_address;
|
||||||
|
this->process_handle = process_h;
|
||||||
|
this->base_address = address;
|
||||||
|
this->size = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Close() {
|
||||||
|
if (this->mapped_address) {
|
||||||
|
if (R_FAILED(svcUnmapProcessMemory(this->mapped_address, this->process_handle, this->base_address, this->size))) {
|
||||||
|
/* TODO: panic(). */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -224,16 +224,12 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo
|
||||||
Result rc = 0xA09;
|
Result rc = 0xA09;
|
||||||
for (unsigned int i = 0; i < NSO_NUM_MAX; i++) {
|
for (unsigned int i = 0; i < NSO_NUM_MAX; i++) {
|
||||||
if (g_nso_present[i]) {
|
if (g_nso_present[i]) {
|
||||||
u64 map_addr = 0;
|
AutoCloseMap nso_map;
|
||||||
if (R_FAILED((rc = MapUtils::LocateSpaceForMap(&map_addr, extents->nso_sizes[i])))) {
|
if (R_FAILED((rc = nso_map.Open(process_h, extents->nso_addresses[i], extents->nso_sizes[i])))) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *map_base = (u8 *)map_addr;
|
u8 *map_base = (u8 *)nso_map.GetMappedAddress();
|
||||||
|
|
||||||
if (R_FAILED((rc = svcMapProcessMemory(map_base, process_h, extents->nso_addresses[i], extents->nso_sizes[i])))) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *f_nso = OpenNso(i, title_id);
|
FILE *f_nso = OpenNso(i, title_id);
|
||||||
if (f_nso == NULL) {
|
if (f_nso == NULL) {
|
||||||
|
@ -243,7 +239,6 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo
|
||||||
for (unsigned int seg = 0; seg < 3; seg++) {
|
for (unsigned int seg = 0; seg < 3; seg++) {
|
||||||
if (R_FAILED((rc = LoadNsoSegment(i, seg, f_nso, map_base, map_base + extents->nso_sizes[i])))) {
|
if (R_FAILED((rc = LoadNsoSegment(i, seg, f_nso, map_base, map_base + extents->nso_sizes[i])))) {
|
||||||
fclose(f_nso);
|
fclose(f_nso);
|
||||||
svcUnmapProcessMemory(map_base, process_h, extents->nso_addresses[i], extents->nso_sizes[i]);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,9 +257,7 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo
|
||||||
u64 bss_base = rw_base + g_nso_headers[i].segments[2].decomp_size, bss_size = g_nso_headers[i].segments[2].align_or_total_size;
|
u64 bss_base = rw_base + g_nso_headers[i].segments[2].decomp_size, bss_size = g_nso_headers[i].segments[2].align_or_total_size;
|
||||||
std::fill(map_base + bss_base, map_base + bss_base + bss_size, 0);
|
std::fill(map_base + bss_base, map_base + bss_base + bss_size, 0);
|
||||||
|
|
||||||
if (R_FAILED((rc = svcUnmapProcessMemory(map_base, process_h, extents->nso_addresses[i], extents->nso_sizes[i])))) {
|
nso_map.Close();
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int seg = 0; seg < 3; seg++) {
|
for (unsigned int seg = 0; seg < 3; seg++) {
|
||||||
u64 size = g_nso_headers[i].segments[seg].decomp_size;
|
u64 size = g_nso_headers[i].segments[seg].decomp_size;
|
||||||
|
@ -283,25 +276,19 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo
|
||||||
|
|
||||||
/* Map in arguments. */
|
/* Map in arguments. */
|
||||||
if (args != NULL && args_size) {
|
if (args != NULL && args_size) {
|
||||||
u64 arg_map_addr = 0;
|
AutoCloseMap args_map;
|
||||||
if (R_FAILED((rc = MapUtils::LocateSpaceForMap(&arg_map_addr, extents->args_size)))) {
|
if (R_FAILED((rc = args_map.Open(process_h, extents->args_address, extents->args_size)))) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
NsoArgument *arg_map_base = (NsoArgument *)arg_map_addr;
|
NsoArgument *arg_map_base = (NsoArgument *)args_map.GetMappedAddress();
|
||||||
|
|
||||||
if (R_FAILED((rc = svcMapProcessMemory(arg_map_base, process_h, extents->args_address, extents->args_size)))) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
arg_map_base->allocated_space = extents->args_size;
|
arg_map_base->allocated_space = extents->args_size;
|
||||||
arg_map_base->args_size = args_size;
|
arg_map_base->args_size = args_size;
|
||||||
std::fill(arg_map_base->_0x8, arg_map_base->_0x8 + sizeof(arg_map_base->_0x8), 0);
|
std::fill(arg_map_base->_0x8, arg_map_base->_0x8 + sizeof(arg_map_base->_0x8), 0);
|
||||||
std::copy(args, args + args_size, arg_map_base->arguments);
|
std::copy(args, args + args_size, arg_map_base->arguments);
|
||||||
|
|
||||||
if (R_FAILED((rc = svcUnmapProcessMemory(arg_map_base, process_h, extents->args_address, extents->args_size)))) {
|
args_map.Close();
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (R_FAILED((rc = svcSetProcessMemoryPermission(process_h, extents->args_address, extents->args_size, 3)))) {
|
if (R_FAILED((rc = svcSetProcessMemoryPermission(process_h, extents->args_address, extents->args_size, 3)))) {
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -104,6 +104,26 @@ void Registration::AddNsoInfo(u64 index, u64 base_address, u64 size, const unsig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result Registration::AddNrrInfo(u64 index, u64 base_address, u64 size, u64 code_memory_address, u64 loader_address) {
|
||||||
|
Registration::Process *target_process = GetProcess(index);
|
||||||
|
if (target_process == NULL) {
|
||||||
|
/* TODO: panic() */
|
||||||
|
return 0x7009;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < NSO_INFO_MAX; i++) {
|
||||||
|
if (!target_process->nrr_infos[i].in_use) {
|
||||||
|
target_process->nrr_infos[i].info.base_address = base_address;
|
||||||
|
target_process->nrr_infos[i].info.size = size;
|
||||||
|
target_process->nrr_infos[i].info.code_memory_address = code_memory_address;
|
||||||
|
target_process->nrr_infos[i].info.loader_address = loader_address;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0x7009;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Result Registration::GetNsoInfosForProcessId(Registration::NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written) {
|
Result Registration::GetNsoInfosForProcessId(Registration::NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written) {
|
||||||
Registration::Process *target_process = GetProcessByProcessId(process_id);
|
Registration::Process *target_process = GetProcessByProcessId(process_id);
|
||||||
if (target_process == NULL) {
|
if (target_process == NULL) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Registration {
|
||||||
u64 base_address;
|
u64 base_address;
|
||||||
u64 size;
|
u64 size;
|
||||||
u64 code_memory_address;
|
u64 code_memory_address;
|
||||||
u64 address_for_loader;
|
u64 loader_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NrrInfoHolder {
|
struct NrrInfoHolder {
|
||||||
|
@ -45,7 +45,7 @@ class Registration {
|
||||||
Registration::TidSid tid_sid;
|
Registration::TidSid tid_sid;
|
||||||
Registration::NsoInfoHolder nso_infos[NSO_INFO_MAX];
|
Registration::NsoInfoHolder nso_infos[NSO_INFO_MAX];
|
||||||
Registration::NrrInfoHolder nrr_infos[NRR_INFO_MAX];
|
Registration::NrrInfoHolder nrr_infos[NRR_INFO_MAX];
|
||||||
u64 _0x730;
|
void *owner_ro_service;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct List {
|
struct List {
|
||||||
|
@ -61,5 +61,6 @@ class Registration {
|
||||||
static bool UnregisterIndex(u64 index);
|
static bool UnregisterIndex(u64 index);
|
||||||
static void SetProcessIdTidMinAndIs64BitAddressSpace(u64 index, u64 process_id, u64 tid_min, bool is_64_bit_addspace);
|
static void SetProcessIdTidMinAndIs64BitAddressSpace(u64 index, u64 process_id, u64 tid_min, bool is_64_bit_addspace);
|
||||||
static void AddNsoInfo(u64 index, u64 base_address, u64 size, const unsigned char *build_id);
|
static void AddNsoInfo(u64 index, u64 base_address, u64 size, const unsigned char *build_id);
|
||||||
|
static Result AddNrrInfo(u64 index, u64 base_address, u64 size, u64 code_memory_address, u64 loader_address);
|
||||||
static Result GetNsoInfosForProcessId(NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written);
|
static Result GetNsoInfosForProcessId(NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "ldr_ro_service.hpp"
|
#include "ldr_ro_service.hpp"
|
||||||
#include "ldr_registration.hpp"
|
#include "ldr_registration.hpp"
|
||||||
|
#include "ldr_map.hpp"
|
||||||
|
|
||||||
Result RelocatableObjectsService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
Result RelocatableObjectsService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
||||||
Result rc = 0xF601;
|
Result rc = 0xF601;
|
||||||
|
@ -42,8 +43,34 @@ std::tuple<Result> RelocatableObjectsService::unload_nro(PidDescriptor pid_desc,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Result> RelocatableObjectsService::load_nrr(PidDescriptor pid_desc, u64 nrr_address, u64 nrr_size) {
|
std::tuple<Result> RelocatableObjectsService::load_nrr(PidDescriptor pid_desc, u64 nrr_address, u64 nrr_size) {
|
||||||
/* TODO */
|
Result rc;
|
||||||
return std::make_tuple(0xF601);
|
Registration::Process *target_proc;
|
||||||
|
if (!this->has_initialized || this->process_id != pid_desc.pid) {
|
||||||
|
rc = 0xAE09;
|
||||||
|
goto LOAD_NRR_END;
|
||||||
|
}
|
||||||
|
if (nrr_address & 0xFFF) {
|
||||||
|
rc = 0xA209;
|
||||||
|
goto LOAD_NRR_END;
|
||||||
|
}
|
||||||
|
if (nrr_address + nrr_size <= nrr_address || !nrr_size || (nrr_size & 0xFFF)) {
|
||||||
|
rc = 0xA409;
|
||||||
|
goto LOAD_NRR_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_proc = Registration::GetProcessByProcessId(pid_desc.pid);
|
||||||
|
if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) {
|
||||||
|
rc = 0xAC09;
|
||||||
|
goto LOAD_NRR_END;
|
||||||
|
}
|
||||||
|
target_proc->owner_ro_service = this;
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Implement remainder of fucntion */
|
||||||
|
rc = 0xDED09;
|
||||||
|
|
||||||
|
LOAD_NRR_END:
|
||||||
|
return std::make_tuple(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Result> RelocatableObjectsService::unload_nrr(PidDescriptor pid_desc, u64 nrr_address) {
|
std::tuple<Result> RelocatableObjectsService::unload_nrr(PidDescriptor pid_desc, u64 nrr_address) {
|
||||||
|
@ -59,6 +86,7 @@ std::tuple<Result> RelocatableObjectsService::initialize(PidDescriptor pid_desc,
|
||||||
svcCloseHandle(this->process_handle);
|
svcCloseHandle(this->process_handle);
|
||||||
}
|
}
|
||||||
this->process_handle = process_h.handle;
|
this->process_handle = process_h.handle;
|
||||||
|
this->process_id = handle_pid;
|
||||||
this->has_initialized = true;
|
this->has_initialized = true;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue