Merge pull request #4480 from wwylele/memory-global-2

Memory: eliminate global state
This commit is contained in:
bunnei
2018-12-06 19:17:28 -05:00
committed by GitHub
57 changed files with 670 additions and 491 deletions

View File

@@ -113,7 +113,7 @@ void Module::CompletionEventCallBack(u64 port_id, s64) {
if (copy_length <= 0) {
break;
}
Memory::WriteBlock(*port.dest_process, dest_ptr, src_ptr, copy_length);
system.Memory().WriteBlock(*port.dest_process, dest_ptr, src_ptr, copy_length);
dest_ptr += copy_length;
dest_size_left -= copy_length;
src_ptr += original_width;
@@ -125,8 +125,8 @@ void Module::CompletionEventCallBack(u64 port_id, s64) {
LOG_ERROR(Service_CAM, "The destination size ({}) doesn't match the source ({})!",
port.dest_size, buffer_size);
}
Memory::WriteBlock(*port.dest_process, port.dest, buffer.data(),
std::min<std::size_t>(port.dest_size, buffer_size));
system.Memory().WriteBlock(*port.dest_process, port.dest, buffer.data(),
std::min<std::size_t>(port.dest_size, buffer_size));
}
port.is_receiving = false;

View File

@@ -491,6 +491,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
// GX request DMA - typically used for copying memory from GSP heap to VRAM
case CommandId::REQUEST_DMA: {
MICROPROFILE_SCOPE(GPU_GSP_DMA);
Memory::MemorySystem& memory = Core::System::GetInstance().Memory();
// TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever
// possible/likely
@@ -502,9 +503,9 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
// TODO(Subv): These memory accesses should not go through the application's memory mapping.
// They should go through the GSP module's memory mapping.
Memory::CopyBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(),
command.dma_request.dest_address, command.dma_request.source_address,
command.dma_request.size);
memory.CopyBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(),
command.dma_request.dest_address, command.dma_request.source_address,
command.dma_request.size);
SignalInterrupt(InterruptId::DMA);
break;
}

View File

@@ -55,7 +55,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const {
return 0;
SegmentEntry entry;
GetEntry(segment_tag.segment_index, entry);
GetEntry(memory, segment_tag.segment_index, entry);
if (segment_tag.offset_into_segment >= entry.size)
return 0;
@@ -71,11 +71,11 @@ ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType reloc
break;
case RelocationType::AbsoluteAddress:
case RelocationType::AbsoluteAddress2:
Memory::Write32(target_address, symbol_address + addend);
memory.Write32(target_address, symbol_address + addend);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::RelativeAddress:
Memory::Write32(target_address, symbol_address + addend - target_future_address);
memory.Write32(target_address, symbol_address + addend - target_future_address);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::ThumbBranch:
@@ -98,7 +98,7 @@ ResultCode CROHelper::ClearRelocation(VAddr target_address, RelocationType reloc
case RelocationType::AbsoluteAddress:
case RelocationType::AbsoluteAddress2:
case RelocationType::RelativeAddress:
Memory::Write32(target_address, 0);
memory.Write32(target_address, 0);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::ThumbBranch:
@@ -121,7 +121,7 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
VAddr relocation_address = batch;
while (true) {
RelocationEntry relocation;
Memory::ReadBlock(process, relocation_address, &relocation, sizeof(RelocationEntry));
memory.ReadBlock(process, relocation_address, &relocation, sizeof(RelocationEntry));
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
if (relocation_target == 0) {
@@ -142,9 +142,9 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
}
RelocationEntry relocation;
Memory::ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
memory.ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
relocation.is_batch_resolved = reset ? 0 : 1;
Memory::WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
memory.WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
return RESULT_SUCCESS;
}
@@ -154,13 +154,13 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
std::size_t len = name.size();
ExportTreeEntry entry;
GetEntry(0, entry);
GetEntry(memory, 0, entry);
ExportTreeEntry::Child next;
next.raw = entry.left.raw;
u32 found_id;
while (true) {
GetEntry(next.next_index, entry);
GetEntry(memory, next.next_index, entry);
if (next.is_end) {
found_id = entry.export_table_index;
@@ -186,9 +186,9 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
u32 export_strings_size = GetField(ExportStringsSize);
ExportNamedSymbolEntry symbol_entry;
GetEntry(found_id, symbol_entry);
GetEntry(memory, found_id, symbol_entry);
if (Memory::ReadCString(symbol_entry.name_offset, export_strings_size) != name)
if (memory.ReadCString(symbol_entry.name_offset, export_strings_size) != name)
return 0;
return SegmentTagToAddress(symbol_entry.symbol_position);
@@ -279,7 +279,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
u32 segment_num = GetField(SegmentNum);
for (u32 i = 0; i < segment_num; ++i) {
SegmentEntry segment;
GetEntry(i, segment);
GetEntry(memory, i, segment);
if (segment.type == SegmentType::Data) {
if (segment.size != 0) {
if (segment.size > data_segment_size)
@@ -298,7 +298,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
if (segment.offset > module_address + cro_size)
return CROFormatError(0x19);
}
SetEntry(i, segment);
SetEntry(memory, i, segment);
}
return MakeResult<u32>(prev_data_segment + module_address);
}
@@ -310,7 +310,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
for (u32 i = 0; i < export_named_symbol_num; ++i) {
ExportNamedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.name_offset != 0) {
entry.name_offset += module_address;
@@ -320,7 +320,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
}
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
return RESULT_SUCCESS;
}
@@ -329,7 +329,7 @@ ResultCode CROHelper::VerifyExportTreeTable() const {
u32 tree_num = GetField(ExportTreeNum);
for (u32 i = 0; i < tree_num; ++i) {
ExportTreeEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.left.next_index >= tree_num || entry.right.next_index >= tree_num) {
return CROFormatError(0x11);
@@ -353,7 +353,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
u32 module_num = GetField(ImportModuleNum);
for (u32 i = 0; i < module_num; ++i) {
ImportModuleEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.name_offset != 0) {
entry.name_offset += module_address;
@@ -379,7 +379,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
}
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
return RESULT_SUCCESS;
}
@@ -395,7 +395,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
u32 num = GetField(ImportNamedSymbolNum);
for (u32 i = 0; i < num; ++i) {
ImportNamedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.name_offset != 0) {
entry.name_offset += module_address;
@@ -413,7 +413,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
}
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
return RESULT_SUCCESS;
}
@@ -427,7 +427,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
u32 num = GetField(ImportIndexedSymbolNum);
for (u32 i = 0; i < num; ++i) {
ImportIndexedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.relocation_batch_offset != 0) {
entry.relocation_batch_offset += module_address;
@@ -437,7 +437,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
}
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
return RESULT_SUCCESS;
}
@@ -451,7 +451,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
u32 num = GetField(ImportAnonymousSymbolNum);
for (u32 i = 0; i < num; ++i) {
ImportAnonymousSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.relocation_batch_offset != 0) {
entry.relocation_batch_offset += module_address;
@@ -461,7 +461,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
}
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
return RESULT_SUCCESS;
}
@@ -476,14 +476,14 @@ ResultCode CROHelper::ResetExternalRelocations() {
ExternalRelocationEntry relocation;
// Verifies that the last relocation is the end of a batch
GetEntry(external_relocation_num - 1, relocation);
GetEntry(memory, external_relocation_num - 1, relocation);
if (!relocation.is_batch_end) {
return CROFormatError(0x12);
}
bool batch_begin = true;
for (u32 i = 0; i < external_relocation_num; ++i) {
GetEntry(i, relocation);
GetEntry(memory, i, relocation);
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
if (relocation_target == 0) {
@@ -500,7 +500,7 @@ ResultCode CROHelper::ResetExternalRelocations() {
if (batch_begin) {
// resets to unresolved state
relocation.is_batch_resolved = 0;
SetEntry(i, relocation);
SetEntry(memory, i, relocation);
}
// if current is an end, then the next is a beginning
@@ -516,7 +516,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
bool batch_begin = true;
for (u32 i = 0; i < external_relocation_num; ++i) {
GetEntry(i, relocation);
GetEntry(memory, i, relocation);
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
if (relocation_target == 0) {
@@ -532,7 +532,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
if (batch_begin) {
// resets to unresolved state
relocation.is_batch_resolved = 0;
SetEntry(i, relocation);
SetEntry(memory, i, relocation);
}
// if current is an end, then the next is a beginning
@@ -548,13 +548,13 @@ ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) {
static_relocation_table_offset +
GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry);
CROHelper crs(crs_address, process);
CROHelper crs(crs_address, process, memory);
u32 offset_export_num = GetField(StaticAnonymousSymbolNum);
LOG_INFO(Service_LDR, "CRO \"{}\" exports {} static anonymous symbols", ModuleName(),
offset_export_num);
for (u32 i = 0; i < offset_export_num; ++i) {
StaticAnonymousSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
u32 batch_address = entry.relocation_batch_offset + module_address;
if (batch_address < static_relocation_table_offset ||
@@ -579,7 +579,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
u32 internal_relocation_num = GetField(InternalRelocationNum);
for (u32 i = 0; i < internal_relocation_num; ++i) {
InternalRelocationEntry relocation;
GetEntry(i, relocation);
GetEntry(memory, i, relocation);
VAddr target_addressB = SegmentTagToAddress(relocation.target_position);
if (target_addressB == 0) {
return CROFormatError(0x15);
@@ -587,7 +587,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
VAddr target_address;
SegmentEntry target_segment;
GetEntry(relocation.target_position.segment_index, target_segment);
GetEntry(memory, relocation.target_position.segment_index, target_segment);
if (target_segment.type == SegmentType::Data) {
// If the relocation is to the .data segment, we need to relocate it in the old buffer
@@ -602,7 +602,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
}
SegmentEntry symbol_segment;
GetEntry(relocation.symbol_segment, symbol_segment);
GetEntry(memory, relocation.symbol_segment, symbol_segment);
LOG_TRACE(Service_LDR, "Internally relocates 0x{:08X} with 0x{:08X}", target_address,
symbol_segment.offset);
ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend,
@@ -619,7 +619,7 @@ ResultCode CROHelper::ClearInternalRelocations() {
u32 internal_relocation_num = GetField(InternalRelocationNum);
for (u32 i = 0; i < internal_relocation_num; ++i) {
InternalRelocationEntry relocation;
GetEntry(i, relocation);
GetEntry(memory, i, relocation);
VAddr target_address = SegmentTagToAddress(relocation.target_position);
if (target_address == 0) {
@@ -639,13 +639,13 @@ void CROHelper::UnrebaseImportAnonymousSymbolTable() {
u32 num = GetField(ImportAnonymousSymbolNum);
for (u32 i = 0; i < num; ++i) {
ImportAnonymousSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.relocation_batch_offset != 0) {
entry.relocation_batch_offset -= module_address;
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
}
@@ -653,13 +653,13 @@ void CROHelper::UnrebaseImportIndexedSymbolTable() {
u32 num = GetField(ImportIndexedSymbolNum);
for (u32 i = 0; i < num; ++i) {
ImportIndexedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.relocation_batch_offset != 0) {
entry.relocation_batch_offset -= module_address;
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
}
@@ -667,7 +667,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
u32 num = GetField(ImportNamedSymbolNum);
for (u32 i = 0; i < num; ++i) {
ImportNamedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.name_offset != 0) {
entry.name_offset -= module_address;
@@ -677,7 +677,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
entry.relocation_batch_offset -= module_address;
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
}
@@ -685,7 +685,7 @@ void CROHelper::UnrebaseImportModuleTable() {
u32 module_num = GetField(ImportModuleNum);
for (u32 i = 0; i < module_num; ++i) {
ImportModuleEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.name_offset != 0) {
entry.name_offset -= module_address;
@@ -699,7 +699,7 @@ void CROHelper::UnrebaseImportModuleTable() {
entry.import_anonymous_symbol_table_offset -= module_address;
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
}
@@ -707,13 +707,13 @@ void CROHelper::UnrebaseExportNamedSymbolTable() {
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
for (u32 i = 0; i < export_named_symbol_num; ++i) {
ExportNamedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.name_offset != 0) {
entry.name_offset -= module_address;
}
SetEntry(i, entry);
SetEntry(memory, i, entry);
}
}
@@ -721,7 +721,7 @@ void CROHelper::UnrebaseSegmentTable() {
u32 segment_num = GetField(SegmentNum);
for (u32 i = 0; i < segment_num; ++i) {
SegmentEntry segment;
GetEntry(i, segment);
GetEntry(memory, i, segment);
if (segment.type == SegmentType::BSS) {
segment.offset = 0;
@@ -729,7 +729,7 @@ void CROHelper::UnrebaseSegmentTable() {
segment.offset -= module_address;
}
SetEntry(i, segment);
SetEntry(memory, i, segment);
}
}
@@ -751,17 +751,17 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) {
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
for (u32 i = 0; i < symbol_import_num; ++i) {
ImportNamedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
VAddr relocation_addr = entry.relocation_batch_offset;
ExternalRelocationEntry relocation_entry;
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
memory.ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
if (!relocation_entry.is_batch_resolved) {
ResultCode result =
ForEachAutoLinkCRO(process, crs_address, [&](CROHelper source) -> ResultVal<bool> {
ResultCode result = ForEachAutoLinkCRO(
process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
std::string symbol_name =
Memory::ReadCString(entry.name_offset, import_strings_size);
memory.ReadCString(entry.name_offset, import_strings_size);
u32 symbol_address = source.FindExportNamedSymbol(symbol_name);
if (symbol_address != 0) {
@@ -794,11 +794,11 @@ ResultCode CROHelper::ResetImportNamedSymbol() {
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
for (u32 i = 0; i < symbol_import_num; ++i) {
ImportNamedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
VAddr relocation_addr = entry.relocation_batch_offset;
ExternalRelocationEntry relocation_entry;
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
memory.ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
if (result.IsError()) {
@@ -815,11 +815,11 @@ ResultCode CROHelper::ResetImportIndexedSymbol() {
u32 import_num = GetField(ImportIndexedSymbolNum);
for (u32 i = 0; i < import_num; ++i) {
ImportIndexedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
VAddr relocation_addr = entry.relocation_batch_offset;
ExternalRelocationEntry relocation_entry;
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
memory.ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
if (result.IsError()) {
@@ -836,11 +836,11 @@ ResultCode CROHelper::ResetImportAnonymousSymbol() {
u32 import_num = GetField(ImportAnonymousSymbolNum);
for (u32 i = 0; i < import_num; ++i) {
ImportAnonymousSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
VAddr relocation_addr = entry.relocation_batch_offset;
ExternalRelocationEntry relocation_entry;
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
memory.ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
if (result.IsError()) {
@@ -857,19 +857,19 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
u32 import_module_num = GetField(ImportModuleNum);
for (u32 i = 0; i < import_module_num; ++i) {
ImportModuleEntry entry;
GetEntry(i, entry);
std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size);
GetEntry(memory, i, entry);
std::string want_cro_name = memory.ReadCString(entry.name_offset, import_strings_size);
ResultCode result =
ForEachAutoLinkCRO(process, crs_address, [&](CROHelper source) -> ResultVal<bool> {
ResultCode result = ForEachAutoLinkCRO(
process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
if (want_cro_name == source.ModuleName()) {
LOG_INFO(Service_LDR, "CRO \"{}\" imports {} indexed symbols from \"{}\"",
ModuleName(), entry.import_indexed_symbol_num, source.ModuleName());
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
ImportIndexedSymbolEntry im;
entry.GetImportIndexedSymbolEntry(process, j, im);
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
ExportIndexedSymbolEntry ex;
source.GetEntry(im.index, ex);
source.GetEntry(memory, im.index, ex);
u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position);
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
ResultCode result =
@@ -884,7 +884,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
ModuleName(), entry.import_anonymous_symbol_num, source.ModuleName());
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
ImportAnonymousSymbolEntry im;
entry.GetImportAnonymousSymbolEntry(process, j, im);
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
u32 symbol_address = source.SegmentTagToAddress(im.symbol_position);
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
ResultCode result =
@@ -913,15 +913,15 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) {
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
for (u32 i = 0; i < target_symbol_import_num; ++i) {
ImportNamedSymbolEntry entry;
target.GetEntry(i, entry);
target.GetEntry(memory, i, entry);
VAddr relocation_addr = entry.relocation_batch_offset;
ExternalRelocationEntry relocation_entry;
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
memory.ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
if (!relocation_entry.is_batch_resolved) {
std::string symbol_name =
Memory::ReadCString(entry.name_offset, target_import_strings_size);
memory.ReadCString(entry.name_offset, target_import_strings_size);
u32 symbol_address = FindExportNamedSymbol(symbol_name);
if (symbol_address != 0) {
LOG_TRACE(Service_LDR, " exports symbol \"{}\"", symbol_name);
@@ -944,15 +944,15 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) {
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
for (u32 i = 0; i < target_symbol_import_num; ++i) {
ImportNamedSymbolEntry entry;
target.GetEntry(i, entry);
target.GetEntry(memory, i, entry);
VAddr relocation_addr = entry.relocation_batch_offset;
ExternalRelocationEntry relocation_entry;
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
memory.ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
if (relocation_entry.is_batch_resolved) {
std::string symbol_name =
Memory::ReadCString(entry.name_offset, target_import_strings_size);
memory.ReadCString(entry.name_offset, target_import_strings_size);
u32 symbol_address = FindExportNamedSymbol(symbol_name);
if (symbol_address != 0) {
LOG_TRACE(Service_LDR, " unexports symbol \"{}\"", symbol_name);
@@ -974,18 +974,18 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
u32 target_import_module_num = target.GetField(ImportModuleNum);
for (u32 i = 0; i < target_import_module_num; ++i) {
ImportModuleEntry entry;
target.GetEntry(i, entry);
target.GetEntry(memory, i, entry);
if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name)
if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name)
continue;
LOG_INFO(Service_LDR, "CRO \"{}\" exports {} indexed symbols to \"{}\"", module_name,
entry.import_indexed_symbol_num, target.ModuleName());
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
ImportIndexedSymbolEntry im;
entry.GetImportIndexedSymbolEntry(process, j, im);
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
ExportIndexedSymbolEntry ex;
GetEntry(im.index, ex);
GetEntry(memory, im.index, ex);
u32 symbol_address = SegmentTagToAddress(ex.symbol_position);
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
ResultCode result =
@@ -1000,7 +1000,7 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
entry.import_anonymous_symbol_num, target.ModuleName());
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
ImportAnonymousSymbolEntry im;
entry.GetImportAnonymousSymbolEntry(process, j, im);
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
u32 symbol_address = SegmentTagToAddress(im.symbol_position);
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
ResultCode result =
@@ -1023,16 +1023,16 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
u32 target_import_module_num = target.GetField(ImportModuleNum);
for (u32 i = 0; i < target_import_module_num; ++i) {
ImportModuleEntry entry;
target.GetEntry(i, entry);
target.GetEntry(memory, i, entry);
if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name)
if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name)
continue;
LOG_DEBUG(Service_LDR, "CRO \"{}\" unexports indexed symbols to \"{}\"", module_name,
target.ModuleName());
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
ImportIndexedSymbolEntry im;
entry.GetImportIndexedSymbolEntry(process, j, im);
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
ResultCode result =
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
if (result.IsError()) {
@@ -1045,7 +1045,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
target.ModuleName());
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
ImportAnonymousSymbolEntry im;
entry.GetImportAnonymousSymbolEntry(process, j, im);
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
ResultCode result =
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
if (result.IsError()) {
@@ -1063,15 +1063,15 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
for (u32 i = 0; i < symbol_import_num; ++i) {
ImportNamedSymbolEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
VAddr relocation_addr = entry.relocation_batch_offset;
ExternalRelocationEntry relocation_entry;
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
memory.ReadBlock(process, relocation_addr, &relocation_entry,
sizeof(ExternalRelocationEntry));
if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
ResultCode result =
ForEachAutoLinkCRO(process, crs_address, [&](CROHelper source) -> ResultVal<bool> {
if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
ResultCode result = ForEachAutoLinkCRO(
process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_");
if (symbol_address != 0) {
@@ -1108,9 +1108,9 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
* @param size the size of the string (table), including the terminating 0
* @returns ResultCode RESULT_SUCCESS if the size matches, otherwise error code.
*/
static ResultCode VerifyStringTableLength(VAddr address, u32 size) {
static ResultCode VerifyStringTableLength(Memory::MemorySystem& memory, VAddr address, u32 size) {
if (size != 0) {
if (Memory::Read8(address + size - 1) != 0)
if (memory.Read8(address + size - 1) != 0)
return CROFormatError(0x0B);
}
return RESULT_SUCCESS;
@@ -1126,7 +1126,7 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
return result;
}
result = VerifyStringTableLength(GetField(ModuleNameOffset), GetField(ModuleNameSize));
result = VerifyStringTableLength(memory, GetField(ModuleNameOffset), GetField(ModuleNameSize));
if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error verifying module name {:08X}", result.raw);
return result;
@@ -1155,7 +1155,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
return result;
}
result = VerifyStringTableLength(GetField(ExportStringsOffset), GetField(ExportStringsSize));
result =
VerifyStringTableLength(memory, GetField(ExportStringsOffset), GetField(ExportStringsSize));
if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error verifying export strings {:08X}", result.raw);
return result;
@@ -1191,7 +1192,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
return result;
}
result = VerifyStringTableLength(GetField(ImportStringsOffset), GetField(ImportStringsSize));
result =
VerifyStringTableLength(memory, GetField(ImportStringsOffset), GetField(ImportStringsSize));
if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error verifying import strings {:08X}", result.raw);
return result;
@@ -1264,11 +1266,11 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
// so we do the same
if (GetField(SegmentNum) >= 2) { // means we have .data segment
SegmentEntry entry;
GetEntry(2, entry);
GetEntry(memory, 2, entry);
ASSERT(entry.type == SegmentType::Data);
data_segment_address = entry.offset;
entry.offset = GetField(DataOffset);
SetEntry(2, entry);
SetEntry(memory, 2, entry);
}
}
SCOPE_EXIT({
@@ -1276,9 +1278,9 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
if (link_on_load_bug_fix) {
if (GetField(SegmentNum) >= 2) {
SegmentEntry entry;
GetEntry(2, entry);
GetEntry(memory, 2, entry);
entry.offset = data_segment_address;
SetEntry(2, entry);
SetEntry(memory, 2, entry);
}
}
});
@@ -1299,17 +1301,18 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
}
// Exports symbols to other modules
result = ForEachAutoLinkCRO(process, crs_address, [this](CROHelper target) -> ResultVal<bool> {
ResultCode result = ApplyExportNamedSymbol(target);
if (result.IsError())
return result;
result = ForEachAutoLinkCRO(process, memory, crs_address,
[this](CROHelper target) -> ResultVal<bool> {
ResultCode result = ApplyExportNamedSymbol(target);
if (result.IsError())
return result;
result = ApplyModuleExport(target);
if (result.IsError())
return result;
result = ApplyModuleExport(target);
if (result.IsError())
return result;
return MakeResult<bool>(true);
});
return MakeResult<bool>(true);
});
if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error applying export {:08X}", result.raw);
return result;
@@ -1343,17 +1346,18 @@ ResultCode CROHelper::Unlink(VAddr crs_address) {
// Resets all symbols in other modules imported from this module
// Note: the RO service seems only searching in auto-link modules
result = ForEachAutoLinkCRO(process, crs_address, [this](CROHelper target) -> ResultVal<bool> {
ResultCode result = ResetExportNamedSymbol(target);
if (result.IsError())
return result;
result = ForEachAutoLinkCRO(process, memory, crs_address,
[this](CROHelper target) -> ResultVal<bool> {
ResultCode result = ResetExportNamedSymbol(target);
if (result.IsError())
return result;
result = ResetModuleExport(target);
if (result.IsError())
return result;
result = ResetModuleExport(target);
if (result.IsError())
return result;
return MakeResult<bool>(true);
});
return MakeResult<bool>(true);
});
if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error resetting export {:08X}", result.raw);
return result;
@@ -1383,13 +1387,13 @@ void CROHelper::InitCRS() {
}
void CROHelper::Register(VAddr crs_address, bool auto_link) {
CROHelper crs(crs_address, process);
CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process);
CROHelper crs(crs_address, process, memory);
CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process, memory);
if (head.module_address) {
// there are already CROs registered
// register as the new tail
CROHelper tail(head.PreviousModule(), process);
CROHelper tail(head.PreviousModule(), process, memory);
// link with the old tail
ASSERT(tail.NextModule() == 0);
@@ -1415,9 +1419,11 @@ void CROHelper::Register(VAddr crs_address, bool auto_link) {
}
void CROHelper::Unregister(VAddr crs_address) {
CROHelper crs(crs_address, process);
CROHelper next_head(crs.NextModule(), process), previous_head(crs.PreviousModule(), process);
CROHelper next(NextModule(), process), previous(PreviousModule(), process);
CROHelper crs(crs_address, process, memory);
CROHelper next_head(crs.NextModule(), process, memory);
CROHelper previous_head(crs.PreviousModule(), process, memory);
CROHelper next(NextModule(), process, memory);
CROHelper previous(PreviousModule(), process, memory);
if (module_address == next_head.module_address ||
module_address == previous_head.module_address) {
@@ -1511,7 +1517,7 @@ std::tuple<VAddr, u32> CROHelper::GetExecutablePages() const {
u32 segment_num = GetField(SegmentNum);
for (u32 i = 0; i < segment_num; ++i) {
SegmentEntry entry;
GetEntry(i, entry);
GetEntry(memory, i, entry);
if (entry.type == SegmentType::Code && entry.size != 0) {
VAddr begin = Common::AlignDown(entry.offset, Memory::PAGE_SIZE);
VAddr end = Common::AlignUp(entry.offset + entry.size, Memory::PAGE_SIZE);

View File

@@ -40,11 +40,11 @@ static constexpr u32 CRO_HASH_SIZE = 0x80;
class CROHelper final {
public:
// TODO (wwylele): pass in the process handle for memory access
explicit CROHelper(VAddr cro_address, Kernel::Process& process)
: module_address(cro_address), process(process) {}
explicit CROHelper(VAddr cro_address, Kernel::Process& process, Memory::MemorySystem& memory)
: module_address(cro_address), process(process), memory(memory) {}
std::string ModuleName() const {
return Memory::ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
return memory.ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
}
u32 GetFileSize() const {
@@ -150,6 +150,7 @@ public:
private:
const VAddr module_address; ///< the virtual address of this module
Kernel::Process& process; ///< the owner process of this module
Memory::MemorySystem& memory;
/**
* Each item in this enum represents a u32 field in the header begin from address+0x80,
@@ -317,20 +318,20 @@ private:
static constexpr HeaderField TABLE_OFFSET_FIELD = ImportModuleTableOffset;
void GetImportIndexedSymbolEntry(Kernel::Process& process, u32 index,
ImportIndexedSymbolEntry& entry) {
Memory::ReadBlock(process,
import_indexed_symbol_table_offset +
index * sizeof(ImportIndexedSymbolEntry),
&entry, sizeof(ImportIndexedSymbolEntry));
void GetImportIndexedSymbolEntry(Kernel::Process& process, Memory::MemorySystem& memory,
u32 index, ImportIndexedSymbolEntry& entry) {
memory.ReadBlock(process,
import_indexed_symbol_table_offset +
index * sizeof(ImportIndexedSymbolEntry),
&entry, sizeof(ImportIndexedSymbolEntry));
}
void GetImportAnonymousSymbolEntry(Kernel::Process& process, u32 index,
ImportAnonymousSymbolEntry& entry) {
Memory::ReadBlock(process,
import_anonymous_symbol_table_offset +
index * sizeof(ImportAnonymousSymbolEntry),
&entry, sizeof(ImportAnonymousSymbolEntry));
void GetImportAnonymousSymbolEntry(Kernel::Process& process, Memory::MemorySystem& memory,
u32 index, ImportAnonymousSymbolEntry& entry) {
memory.ReadBlock(process,
import_anonymous_symbol_table_offset +
index * sizeof(ImportAnonymousSymbolEntry),
&entry, sizeof(ImportAnonymousSymbolEntry));
}
};
ASSERT_CRO_STRUCT(ImportModuleEntry, 20);
@@ -407,11 +408,11 @@ private:
}
u32 GetField(HeaderField field) const {
return Memory::Read32(Field(field));
return memory.Read32(Field(field));
}
void SetField(HeaderField field, u32 value) {
Memory::Write32(Field(field), value);
memory.Write32(Field(field), value);
}
/**
@@ -422,10 +423,10 @@ private:
* indicating which table the entry is in.
*/
template <typename T>
void GetEntry(std::size_t index, T& data) const {
Memory::ReadBlock(process,
GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
&data, sizeof(T));
void GetEntry(Memory::MemorySystem& memory, std::size_t index, T& data) const {
memory.ReadBlock(process,
GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
&data, sizeof(T));
}
/**
@@ -436,10 +437,10 @@ private:
* indicating which table the entry is in.
*/
template <typename T>
void SetEntry(std::size_t index, const T& data) {
Memory::WriteBlock(process,
GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
&data, sizeof(T));
void SetEntry(Memory::MemorySystem& memory, std::size_t index, const T& data) {
memory.WriteBlock(process,
GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
&data, sizeof(T));
}
/**
@@ -478,11 +479,11 @@ private:
* otherwise error code of the last iteration.
*/
template <typename FunctionObject>
static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, VAddr crs_address,
FunctionObject func) {
static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, Memory::MemorySystem& memory,
VAddr crs_address, FunctionObject func) {
VAddr current = crs_address;
while (current != 0) {
CROHelper cro(current, process);
CROHelper cro(current, process, memory);
CASCADE_RESULT(bool next, func(cro));
if (!next)
break;

View File

@@ -115,7 +115,7 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) {
return;
}
CROHelper crs(crs_address, *process);
CROHelper crs(crs_address, *process, system.Memory());
crs.InitCRS();
result = crs.Rebase(0, crs_size, 0, 0, 0, 0, true);
@@ -249,7 +249,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) {
return;
}
CROHelper cro(cro_address, *process);
CROHelper cro(cro_address, *process, system.Memory());
result = cro.VerifyHash(cro_size, crr_address);
if (result.IsError()) {
@@ -331,7 +331,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}, zero={}, cro_buffer_ptr=0x{:08X}",
cro_address, zero, cro_buffer_ptr);
CROHelper cro(cro_address, *process);
CROHelper cro(cro_address, *process, system.Memory());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@@ -398,7 +398,7 @@ void RO::LinkCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address);
CROHelper cro(cro_address, *process);
CROHelper cro(cro_address, *process, system.Memory());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@@ -438,7 +438,7 @@ void RO::UnlinkCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address);
CROHelper cro(cro_address, *process);
CROHelper cro(cro_address, *process, system.Memory());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@@ -487,7 +487,7 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) {
return;
}
CROHelper crs(slot->loaded_crs, *process);
CROHelper crs(slot->loaded_crs, *process, system.Memory());
crs.Unrebase(true);
ResultCode result = RESULT_SUCCESS;
@@ -502,7 +502,7 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) {
rb.Push(result);
}
RO::RO() : ServiceFramework("ldr:ro", 2) {
RO::RO(Core::System& system) : ServiceFramework("ldr:ro", 2), system(system) {
static const FunctionInfo functions[] = {
{0x000100C2, &RO::Initialize, "Initialize"},
{0x00020082, &RO::LoadCRR, "LoadCRR"},
@@ -519,7 +519,7 @@ RO::RO() : ServiceFramework("ldr:ro", 2) {
void InstallInterfaces(Core::System& system) {
auto& service_manager = system.ServiceManager();
std::make_shared<RO>()->InstallAsService(service_manager);
std::make_shared<RO>(system)->InstallAsService(service_manager);
}
} // namespace Service::LDR

View File

@@ -18,7 +18,7 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase {
class RO final : public ServiceFramework<RO, ClientSlot> {
public:
RO();
explicit RO(Core::System& system);
private:
/**
@@ -149,6 +149,8 @@ private:
* 1 : Result of function, 0 on success, otherwise error code
*/
void Shutdown(Kernel::HLERequestContext& self);
Core::System& system;
};
void InstallInterfaces(Core::System& system);

View File

@@ -180,7 +180,8 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_ses
Kernel::KernelSystem& kernel = Core::System::GetInstance().Kernel();
auto thread = kernel.GetThreadManager().GetCurrentThread();
// TODO(wwylele): avoid GetPointer
u32* cmd_buf = reinterpret_cast<u32*>(Memory::GetPointer(thread->GetCommandBufferAddress()));
u32* cmd_buf = reinterpret_cast<u32*>(
Core::System::GetInstance().Memory().GetPointer(thread->GetCommandBufferAddress()));
u32 header_code = cmd_buf[0];
auto itr = handlers.find(header_code);