ro: move in use trackers outside of info objects

This commit is contained in:
Michael Scire 2020-02-24 16:47:07 -08:00
parent 05a24b5726
commit f427c3d7a5

View file

@ -55,7 +55,6 @@ namespace ams::ro::impl {
u64 code_size; u64 code_size;
u64 rw_size; u64 rw_size;
ModuleId module_id; ModuleId module_id;
bool in_use;
}; };
struct NrrInfo { struct NrrInfo {
@ -63,10 +62,11 @@ namespace ams::ro::impl {
u64 nrr_heap_address; u64 nrr_heap_address;
u64 nrr_heap_size; u64 nrr_heap_size;
u64 mapped_code_address; u64 mapped_code_address;
bool in_use;
}; };
struct ProcessContext { struct ProcessContext {
bool nro_in_use[MaxNroInfos];
bool nrr_in_use[MaxNrrInfos];
NroInfo nro_infos[MaxNroInfos]; NroInfo nro_infos[MaxNroInfos];
NrrInfo nrr_infos[MaxNrrInfos]; NrrInfo nrr_infos[MaxNrrInfos];
Handle process_handle; Handle process_handle;
@ -93,7 +93,7 @@ namespace ams::ro::impl {
Result GetNrrInfoByAddress(NrrInfo **out, u64 nrr_heap_address) { Result GetNrrInfoByAddress(NrrInfo **out, u64 nrr_heap_address) {
for (size_t i = 0; i < MaxNrrInfos; i++) { for (size_t i = 0; i < MaxNrrInfos; i++) {
if (this->nrr_infos[i].in_use && this->nrr_infos[i].nrr_heap_address == nrr_heap_address) { if (this->nrr_in_use[i] && this->nrr_infos[i].nrr_heap_address == nrr_heap_address) {
if (out != nullptr) { if (out != nullptr) {
*out = &this->nrr_infos[i]; *out = &this->nrr_infos[i];
} }
@ -105,7 +105,7 @@ namespace ams::ro::impl {
Result GetFreeNrrInfo(NrrInfo **out) { Result GetFreeNrrInfo(NrrInfo **out) {
for (size_t i = 0; i < MaxNrrInfos; i++) { for (size_t i = 0; i < MaxNrrInfos; i++) {
if (!this->nrr_infos[i].in_use) { if (!this->nrr_in_use[i]) {
if (out != nullptr) { if (out != nullptr) {
*out = &this->nrr_infos[i]; *out = &this->nrr_infos[i];
} }
@ -117,7 +117,7 @@ namespace ams::ro::impl {
Result GetNroInfoByAddress(NroInfo **out, u64 nro_address) { Result GetNroInfoByAddress(NroInfo **out, u64 nro_address) {
for (size_t i = 0; i < MaxNroInfos; i++) { for (size_t i = 0; i < MaxNroInfos; i++) {
if (this->nro_infos[i].in_use && this->nro_infos[i].base_address == nro_address) { if (this->nro_in_use[i] && this->nro_infos[i].base_address == nro_address) {
if (out != nullptr) { if (out != nullptr) {
*out = &this->nro_infos[i]; *out = &this->nro_infos[i];
} }
@ -129,7 +129,7 @@ namespace ams::ro::impl {
Result GetNroInfoByModuleId(NroInfo **out, const ModuleId *module_id) { Result GetNroInfoByModuleId(NroInfo **out, const ModuleId *module_id) {
for (size_t i = 0; i < MaxNroInfos; i++) { for (size_t i = 0; i < MaxNroInfos; i++) {
if (this->nro_infos[i].in_use && std::memcmp(&this->nro_infos[i].module_id, module_id, sizeof(*module_id)) == 0) { if (this->nro_in_use[i] && std::memcmp(&this->nro_infos[i].module_id, module_id, sizeof(*module_id)) == 0) {
if (out != nullptr) { if (out != nullptr) {
*out = &this->nro_infos[i]; *out = &this->nro_infos[i];
} }
@ -141,7 +141,7 @@ namespace ams::ro::impl {
Result GetFreeNroInfo(NroInfo **out) { Result GetFreeNroInfo(NroInfo **out) {
for (size_t i = 0; i < MaxNroInfos; i++) { for (size_t i = 0; i < MaxNroInfos; i++) {
if (!this->nro_infos[i].in_use) { if (!this->nro_in_use[i]) {
if (out != nullptr) { if (out != nullptr) {
*out = &this->nro_infos[i]; *out = &this->nro_infos[i];
} }
@ -157,7 +157,7 @@ namespace ams::ro::impl {
sha256CalculateHash(&hash, nro_header, nro_header->GetSize()); sha256CalculateHash(&hash, nro_header, nro_header->GetSize());
for (size_t i = 0; i < MaxNrrInfos; i++) { for (size_t i = 0; i < MaxNrrInfos; i++) {
if (this->nrr_infos[i].in_use) { if (this->nrr_in_use[i]) {
const NrrHeader *nrr_header = this->nrr_infos[i].header; const NrrHeader *nrr_header = this->nrr_infos[i].header;
const Sha256Hash *nro_hashes = reinterpret_cast<const Sha256Hash *>(nrr_header->GetHashes()); const Sha256Hash *nro_hashes = reinterpret_cast<const Sha256Hash *>(nrr_header->GetHashes());
R_UNLESS(!std::binary_search(nro_hashes, nro_hashes + nrr_header->GetNumHashes(), hash), ResultSuccess()); R_UNLESS(!std::binary_search(nro_hashes, nro_hashes + nrr_header->GetNumHashes(), hash), ResultSuccess());
@ -227,6 +227,18 @@ namespace ams::ro::impl {
*out_rw_size = rw_size; *out_rw_size = rw_size;
return ResultSuccess(); return ResultSuccess();
} }
void SetNrrInfoInUse(const NrrInfo *info, bool in_use) {
AMS_ASSERT(std::addressof(this->nrr_infos[0]) <= info && info <= std::addressof(this->nrr_infos[MaxNrrInfos - 1]));
const size_t index = info - std::addressof(this->nrr_infos[0]);
this->nrr_in_use[index] = in_use;
}
void SetNroInfoInUse(const NroInfo *info, bool in_use) {
AMS_ASSERT(std::addressof(this->nro_infos[0]) <= info && info <= std::addressof(this->nro_infos[MaxNroInfos - 1]));
const size_t index = info - std::addressof(this->nro_infos[0]);
this->nro_in_use[index] = in_use;
}
}; };
/* Globals. */ /* Globals. */
@ -275,7 +287,7 @@ namespace ams::ro::impl {
if (context != nullptr) { if (context != nullptr) {
if (context->process_handle != INVALID_HANDLE) { if (context->process_handle != INVALID_HANDLE) {
for (size_t i = 0; i < MaxNrrInfos; i++) { for (size_t i = 0; i < MaxNrrInfos; i++) {
if (context->nrr_infos[i].in_use) { if (context->nrr_in_use[i]) {
UnmapNrr(context->process_handle, context->nrr_infos[i].header, context->nrr_infos[i].nrr_heap_address, context->nrr_infos[i].nrr_heap_size, context->nrr_infos[i].mapped_code_address); UnmapNrr(context->process_handle, context->nrr_infos[i].header, context->nrr_infos[i].nrr_heap_address, context->nrr_infos[i].nrr_heap_size, context->nrr_infos[i].mapped_code_address);
} }
} }
@ -385,7 +397,7 @@ namespace ams::ro::impl {
R_TRY(MapAndValidateNrr(&header, &mapped_code_address, context->process_handle, program_id, nrr_address, nrr_size, expected_type, enforce_type)); R_TRY(MapAndValidateNrr(&header, &mapped_code_address, context->process_handle, program_id, nrr_address, nrr_size, expected_type, enforce_type));
/* Set NRR info. */ /* Set NRR info. */
nrr_info->in_use = true; context->SetNrrInfoInUse(nrr_info, true);
nrr_info->header = header; nrr_info->header = header;
nrr_info->nrr_heap_address = nrr_address; nrr_info->nrr_heap_address = nrr_address;
nrr_info->nrr_heap_size = nrr_size; nrr_info->nrr_heap_size = nrr_size;
@ -410,7 +422,7 @@ namespace ams::ro::impl {
const NrrInfo nrr_backup = *nrr_info; const NrrInfo nrr_backup = *nrr_info;
{ {
/* Nintendo does this unconditionally, whether or not the actual unmap succeeds. */ /* Nintendo does this unconditionally, whether or not the actual unmap succeeds. */
nrr_info->in_use = false; context->SetNrrInfoInUse(nrr_info, false);
std::memset(nrr_info, 0, sizeof(*nrr_info)); std::memset(nrr_info, 0, sizeof(*nrr_info));
} }
return UnmapNrr(context->process_handle, nrr_backup.header, nrr_backup.nrr_heap_address, nrr_backup.nrr_heap_size, nrr_backup.mapped_code_address); return UnmapNrr(context->process_handle, nrr_backup.header, nrr_backup.nrr_heap_address, nrr_backup.nrr_heap_size, nrr_backup.mapped_code_address);
@ -455,9 +467,9 @@ namespace ams::ro::impl {
unmap_guard.Cancel(); unmap_guard.Cancel();
} }
context->SetNroInfoInUse(nro_info, true);
nro_info->code_size = rx_size + ro_size; nro_info->code_size = rx_size + ro_size;
nro_info->rw_size = rw_size; nro_info->rw_size = rw_size;
nro_info->in_use = true;
*out_address = nro_info->base_address; *out_address = nro_info->base_address;
return ResultSuccess(); return ResultSuccess();
} }
@ -478,7 +490,7 @@ namespace ams::ro::impl {
const NroInfo nro_backup = *nro_info; const NroInfo nro_backup = *nro_info;
{ {
/* Nintendo does this unconditionally, whether or not the actual unmap succeeds. */ /* Nintendo does this unconditionally, whether or not the actual unmap succeeds. */
nro_info->in_use = false; context->SetNroInfoInUse(nro_info, false);
std::memset(nro_info, 0, sizeof(*nro_info)); std::memset(nro_info, 0, sizeof(*nro_info));
} }
return UnmapNro(context->process_handle, nro_backup.base_address, nro_backup.nro_heap_address, nro_backup.bss_heap_address, nro_backup.bss_heap_size, nro_backup.code_size, nro_backup.rw_size); return UnmapNro(context->process_handle, nro_backup.base_address, nro_backup.nro_heap_address, nro_backup.bss_heap_address, nro_backup.bss_heap_size, nro_backup.code_size, nro_backup.rw_size);
@ -490,11 +502,12 @@ namespace ams::ro::impl {
const ProcessContext *context = GetContextByProcessId(process_id); const ProcessContext *context = GetContextByProcessId(process_id);
if (context != nullptr) { if (context != nullptr) {
for (size_t i = 0; i < MaxNroInfos && count < max_out_count; i++) { for (size_t i = 0; i < MaxNroInfos && count < max_out_count; i++) {
const NroInfo *nro_info = &context->nro_infos[i]; if (!context->nro_in_use[i]) {
if (!nro_info->in_use) {
continue; continue;
} }
const NroInfo *nro_info = &context->nro_infos[i];
/* Just copy out the info. */ /* Just copy out the info. */
LoaderModuleInfo *out_info = &out_infos[count++]; LoaderModuleInfo *out_info = &out_infos[count++];
memcpy(out_info->build_id, &nro_info->module_id, sizeof(nro_info->module_id)); memcpy(out_info->build_id, &nro_info->module_id, sizeof(nro_info->module_id));