mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-03 23:28:48 +00:00 
			
		
		
		
	Core timing 2.0 (#4913)
* Core::Timing: Add multiple timer, one for each core * revert clang-format; work on tests for CoreTiming * Kernel:: Add support for multiple cores, asserts in HandleSyncRequest because Thread->status == WaitIPC * Add some TRACE_LOGs * fix tests * make some adjustments to qt-debugger, cheats and gdbstub(probably still broken) * Make ARM_Interface::id private, rework ARM_Interface ctor * ReRename TimingManager to Timing for smaler diff * addressed review comments
This commit is contained in:
		
							parent
							
								
									e3dbdcbdff
								
							
						
					
					
						commit
						55ec7031cc
					
				
					 32 changed files with 760 additions and 535 deletions
				
			
		| 
						 | 
				
			
			@ -55,7 +55,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const {
 | 
			
		|||
        return 0;
 | 
			
		||||
 | 
			
		||||
    SegmentEntry entry;
 | 
			
		||||
    GetEntry(memory, segment_tag.segment_index, entry);
 | 
			
		||||
    GetEntry(system.Memory(), segment_tag.segment_index, entry);
 | 
			
		||||
 | 
			
		||||
    if (segment_tag.offset_into_segment >= entry.size)
 | 
			
		||||
        return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -71,12 +71,12 @@ ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType reloc
 | 
			
		|||
        break;
 | 
			
		||||
    case RelocationType::AbsoluteAddress:
 | 
			
		||||
    case RelocationType::AbsoluteAddress2:
 | 
			
		||||
        memory.Write32(target_address, symbol_address + addend);
 | 
			
		||||
        cpu.InvalidateCacheRange(target_address, sizeof(u32));
 | 
			
		||||
        system.Memory().Write32(target_address, symbol_address + addend);
 | 
			
		||||
        system.InvalidateCacheRange(target_address, sizeof(u32));
 | 
			
		||||
        break;
 | 
			
		||||
    case RelocationType::RelativeAddress:
 | 
			
		||||
        memory.Write32(target_address, symbol_address + addend - target_future_address);
 | 
			
		||||
        cpu.InvalidateCacheRange(target_address, sizeof(u32));
 | 
			
		||||
        system.Memory().Write32(target_address, symbol_address + addend - target_future_address);
 | 
			
		||||
        system.InvalidateCacheRange(target_address, sizeof(u32));
 | 
			
		||||
        break;
 | 
			
		||||
    case RelocationType::ThumbBranch:
 | 
			
		||||
    case RelocationType::ArmBranch:
 | 
			
		||||
| 
						 | 
				
			
			@ -98,8 +98,8 @@ ResultCode CROHelper::ClearRelocation(VAddr target_address, RelocationType reloc
 | 
			
		|||
    case RelocationType::AbsoluteAddress:
 | 
			
		||||
    case RelocationType::AbsoluteAddress2:
 | 
			
		||||
    case RelocationType::RelativeAddress:
 | 
			
		||||
        memory.Write32(target_address, 0);
 | 
			
		||||
        cpu.InvalidateCacheRange(target_address, sizeof(u32));
 | 
			
		||||
        system.Memory().Write32(target_address, 0);
 | 
			
		||||
        system.InvalidateCacheRange(target_address, sizeof(u32));
 | 
			
		||||
        break;
 | 
			
		||||
    case RelocationType::ThumbBranch:
 | 
			
		||||
    case RelocationType::ArmBranch:
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +121,8 @@ 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));
 | 
			
		||||
        system.Memory().ReadBlock(process, relocation_address, &relocation,
 | 
			
		||||
                                  sizeof(RelocationEntry));
 | 
			
		||||
 | 
			
		||||
        VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
 | 
			
		||||
        if (relocation_target == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -142,9 +143,9 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    RelocationEntry relocation;
 | 
			
		||||
    memory.ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
 | 
			
		||||
    system.Memory().ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
 | 
			
		||||
    relocation.is_batch_resolved = reset ? 0 : 1;
 | 
			
		||||
    memory.WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
 | 
			
		||||
    system.Memory().WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -154,13 +155,13 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
 | 
			
		|||
 | 
			
		||||
    std::size_t len = name.size();
 | 
			
		||||
    ExportTreeEntry entry;
 | 
			
		||||
    GetEntry(memory, 0, entry);
 | 
			
		||||
    GetEntry(system.Memory(), 0, entry);
 | 
			
		||||
    ExportTreeEntry::Child next;
 | 
			
		||||
    next.raw = entry.left.raw;
 | 
			
		||||
    u32 found_id;
 | 
			
		||||
 | 
			
		||||
    while (true) {
 | 
			
		||||
        GetEntry(memory, next.next_index, entry);
 | 
			
		||||
        GetEntry(system.Memory(), next.next_index, entry);
 | 
			
		||||
 | 
			
		||||
        if (next.is_end) {
 | 
			
		||||
            found_id = entry.export_table_index;
 | 
			
		||||
| 
						 | 
				
			
			@ -186,9 +187,9 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
 | 
			
		|||
 | 
			
		||||
    u32 export_strings_size = GetField(ExportStringsSize);
 | 
			
		||||
    ExportNamedSymbolEntry symbol_entry;
 | 
			
		||||
    GetEntry(memory, found_id, symbol_entry);
 | 
			
		||||
    GetEntry(system.Memory(), found_id, symbol_entry);
 | 
			
		||||
 | 
			
		||||
    if (memory.ReadCString(symbol_entry.name_offset, export_strings_size) != name)
 | 
			
		||||
    if (system.Memory().ReadCString(symbol_entry.name_offset, export_strings_size) != name)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    return SegmentTagToAddress(symbol_entry.symbol_position);
 | 
			
		||||
| 
						 | 
				
			
			@ -279,7 +280,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(memory, i, segment);
 | 
			
		||||
        GetEntry(system.Memory(), i, segment);
 | 
			
		||||
        if (segment.type == SegmentType::Data) {
 | 
			
		||||
            if (segment.size != 0) {
 | 
			
		||||
                if (segment.size > data_segment_size)
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +299,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
 | 
			
		|||
            if (segment.offset > module_address + cro_size)
 | 
			
		||||
                return CROFormatError(0x19);
 | 
			
		||||
        }
 | 
			
		||||
        SetEntry(memory, i, segment);
 | 
			
		||||
        SetEntry(system.Memory(), i, segment);
 | 
			
		||||
    }
 | 
			
		||||
    return MakeResult<u32>(prev_data_segment + module_address);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -310,7 +311,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
 | 
			
		|||
    u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < export_named_symbol_num; ++i) {
 | 
			
		||||
        ExportNamedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.name_offset != 0) {
 | 
			
		||||
            entry.name_offset += module_address;
 | 
			
		||||
| 
						 | 
				
			
			@ -320,7 +321,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -329,7 +330,7 @@ ResultCode CROHelper::VerifyExportTreeTable() const {
 | 
			
		|||
    u32 tree_num = GetField(ExportTreeNum);
 | 
			
		||||
    for (u32 i = 0; i < tree_num; ++i) {
 | 
			
		||||
        ExportTreeEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.left.next_index >= tree_num || entry.right.next_index >= tree_num) {
 | 
			
		||||
            return CROFormatError(0x11);
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +354,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
 | 
			
		|||
    u32 module_num = GetField(ImportModuleNum);
 | 
			
		||||
    for (u32 i = 0; i < module_num; ++i) {
 | 
			
		||||
        ImportModuleEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.name_offset != 0) {
 | 
			
		||||
            entry.name_offset += module_address;
 | 
			
		||||
| 
						 | 
				
			
			@ -379,7 +380,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -395,7 +396,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
 | 
			
		|||
    u32 num = GetField(ImportNamedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < num; ++i) {
 | 
			
		||||
        ImportNamedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.name_offset != 0) {
 | 
			
		||||
            entry.name_offset += module_address;
 | 
			
		||||
| 
						 | 
				
			
			@ -413,7 +414,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -427,7 +428,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
 | 
			
		|||
    u32 num = GetField(ImportIndexedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < num; ++i) {
 | 
			
		||||
        ImportIndexedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.relocation_batch_offset != 0) {
 | 
			
		||||
            entry.relocation_batch_offset += module_address;
 | 
			
		||||
| 
						 | 
				
			
			@ -437,7 +438,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -451,7 +452,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
 | 
			
		|||
    u32 num = GetField(ImportAnonymousSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < num; ++i) {
 | 
			
		||||
        ImportAnonymousSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.relocation_batch_offset != 0) {
 | 
			
		||||
            entry.relocation_batch_offset += module_address;
 | 
			
		||||
| 
						 | 
				
			
			@ -461,7 +462,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -476,14 +477,14 @@ ResultCode CROHelper::ResetExternalRelocations() {
 | 
			
		|||
    ExternalRelocationEntry relocation;
 | 
			
		||||
 | 
			
		||||
    // Verifies that the last relocation is the end of a batch
 | 
			
		||||
    GetEntry(memory, external_relocation_num - 1, relocation);
 | 
			
		||||
    GetEntry(system.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(memory, i, relocation);
 | 
			
		||||
        GetEntry(system.Memory(), i, relocation);
 | 
			
		||||
        VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
 | 
			
		||||
 | 
			
		||||
        if (relocation_target == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -500,7 +501,7 @@ ResultCode CROHelper::ResetExternalRelocations() {
 | 
			
		|||
        if (batch_begin) {
 | 
			
		||||
            // resets to unresolved state
 | 
			
		||||
            relocation.is_batch_resolved = 0;
 | 
			
		||||
            SetEntry(memory, i, relocation);
 | 
			
		||||
            SetEntry(system.Memory(), i, relocation);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if current is an end, then the next is a beginning
 | 
			
		||||
| 
						 | 
				
			
			@ -516,7 +517,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
 | 
			
		|||
 | 
			
		||||
    bool batch_begin = true;
 | 
			
		||||
    for (u32 i = 0; i < external_relocation_num; ++i) {
 | 
			
		||||
        GetEntry(memory, i, relocation);
 | 
			
		||||
        GetEntry(system.Memory(), i, relocation);
 | 
			
		||||
        VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
 | 
			
		||||
 | 
			
		||||
        if (relocation_target == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -532,7 +533,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
 | 
			
		|||
        if (batch_begin) {
 | 
			
		||||
            // resets to unresolved state
 | 
			
		||||
            relocation.is_batch_resolved = 0;
 | 
			
		||||
            SetEntry(memory, i, relocation);
 | 
			
		||||
            SetEntry(system.Memory(), i, relocation);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if current is an end, then the next is a beginning
 | 
			
		||||
| 
						 | 
				
			
			@ -548,13 +549,13 @@ ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) {
 | 
			
		|||
        static_relocation_table_offset +
 | 
			
		||||
        GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry);
 | 
			
		||||
 | 
			
		||||
    CROHelper crs(crs_address, process, memory, cpu);
 | 
			
		||||
    CROHelper crs(crs_address, process, system);
 | 
			
		||||
    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(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        u32 batch_address = entry.relocation_batch_offset + module_address;
 | 
			
		||||
 | 
			
		||||
        if (batch_address < static_relocation_table_offset ||
 | 
			
		||||
| 
						 | 
				
			
			@ -579,7 +580,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(memory, i, relocation);
 | 
			
		||||
        GetEntry(system.Memory(), i, relocation);
 | 
			
		||||
        VAddr target_addressB = SegmentTagToAddress(relocation.target_position);
 | 
			
		||||
        if (target_addressB == 0) {
 | 
			
		||||
            return CROFormatError(0x15);
 | 
			
		||||
| 
						 | 
				
			
			@ -587,7 +588,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
 | 
			
		|||
 | 
			
		||||
        VAddr target_address;
 | 
			
		||||
        SegmentEntry target_segment;
 | 
			
		||||
        GetEntry(memory, relocation.target_position.segment_index, target_segment);
 | 
			
		||||
        GetEntry(system.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 +603,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        SegmentEntry symbol_segment;
 | 
			
		||||
        GetEntry(memory, relocation.symbol_segment, symbol_segment);
 | 
			
		||||
        GetEntry(system.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 +620,7 @@ ResultCode CROHelper::ClearInternalRelocations() {
 | 
			
		|||
    u32 internal_relocation_num = GetField(InternalRelocationNum);
 | 
			
		||||
    for (u32 i = 0; i < internal_relocation_num; ++i) {
 | 
			
		||||
        InternalRelocationEntry relocation;
 | 
			
		||||
        GetEntry(memory, i, relocation);
 | 
			
		||||
        GetEntry(system.Memory(), i, relocation);
 | 
			
		||||
        VAddr target_address = SegmentTagToAddress(relocation.target_position);
 | 
			
		||||
 | 
			
		||||
        if (target_address == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -639,13 +640,13 @@ void CROHelper::UnrebaseImportAnonymousSymbolTable() {
 | 
			
		|||
    u32 num = GetField(ImportAnonymousSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < num; ++i) {
 | 
			
		||||
        ImportAnonymousSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.relocation_batch_offset != 0) {
 | 
			
		||||
            entry.relocation_batch_offset -= module_address;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -653,13 +654,13 @@ void CROHelper::UnrebaseImportIndexedSymbolTable() {
 | 
			
		|||
    u32 num = GetField(ImportIndexedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < num; ++i) {
 | 
			
		||||
        ImportIndexedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.relocation_batch_offset != 0) {
 | 
			
		||||
            entry.relocation_batch_offset -= module_address;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -667,7 +668,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
 | 
			
		|||
    u32 num = GetField(ImportNamedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < num; ++i) {
 | 
			
		||||
        ImportNamedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.name_offset != 0) {
 | 
			
		||||
            entry.name_offset -= module_address;
 | 
			
		||||
| 
						 | 
				
			
			@ -677,7 +678,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
 | 
			
		|||
            entry.relocation_batch_offset -= module_address;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -685,7 +686,7 @@ void CROHelper::UnrebaseImportModuleTable() {
 | 
			
		|||
    u32 module_num = GetField(ImportModuleNum);
 | 
			
		||||
    for (u32 i = 0; i < module_num; ++i) {
 | 
			
		||||
        ImportModuleEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.name_offset != 0) {
 | 
			
		||||
            entry.name_offset -= module_address;
 | 
			
		||||
| 
						 | 
				
			
			@ -699,7 +700,7 @@ void CROHelper::UnrebaseImportModuleTable() {
 | 
			
		|||
            entry.import_anonymous_symbol_table_offset -= module_address;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -707,13 +708,13 @@ void CROHelper::UnrebaseExportNamedSymbolTable() {
 | 
			
		|||
    u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < export_named_symbol_num; ++i) {
 | 
			
		||||
        ExportNamedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (entry.name_offset != 0) {
 | 
			
		||||
            entry.name_offset -= module_address;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, entry);
 | 
			
		||||
        SetEntry(system.Memory(), i, entry);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -721,7 +722,7 @@ void CROHelper::UnrebaseSegmentTable() {
 | 
			
		|||
    u32 segment_num = GetField(SegmentNum);
 | 
			
		||||
    for (u32 i = 0; i < segment_num; ++i) {
 | 
			
		||||
        SegmentEntry segment;
 | 
			
		||||
        GetEntry(memory, i, segment);
 | 
			
		||||
        GetEntry(system.Memory(), i, segment);
 | 
			
		||||
 | 
			
		||||
        if (segment.type == SegmentType::BSS) {
 | 
			
		||||
            segment.offset = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -729,7 +730,7 @@ void CROHelper::UnrebaseSegmentTable() {
 | 
			
		|||
            segment.offset -= module_address;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SetEntry(memory, i, segment);
 | 
			
		||||
        SetEntry(system.Memory(), i, segment);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -751,17 +752,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(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        VAddr relocation_addr = entry.relocation_batch_offset;
 | 
			
		||||
        ExternalRelocationEntry relocation_entry;
 | 
			
		||||
        memory.ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                         sizeof(ExternalRelocationEntry));
 | 
			
		||||
        system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                                  sizeof(ExternalRelocationEntry));
 | 
			
		||||
 | 
			
		||||
        if (!relocation_entry.is_batch_resolved) {
 | 
			
		||||
            ResultCode result = ForEachAutoLinkCRO(
 | 
			
		||||
                process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
 | 
			
		||||
                process, system, crs_address, [&](CROHelper source) -> ResultVal<bool> {
 | 
			
		||||
                    std::string symbol_name =
 | 
			
		||||
                        memory.ReadCString(entry.name_offset, import_strings_size);
 | 
			
		||||
                        system.Memory().ReadCString(entry.name_offset, import_strings_size);
 | 
			
		||||
                    u32 symbol_address = source.FindExportNamedSymbol(symbol_name);
 | 
			
		||||
 | 
			
		||||
                    if (symbol_address != 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -794,11 +795,11 @@ ResultCode CROHelper::ResetImportNamedSymbol() {
 | 
			
		|||
    u32 symbol_import_num = GetField(ImportNamedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < symbol_import_num; ++i) {
 | 
			
		||||
        ImportNamedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        VAddr relocation_addr = entry.relocation_batch_offset;
 | 
			
		||||
        ExternalRelocationEntry relocation_entry;
 | 
			
		||||
        memory.ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                         sizeof(ExternalRelocationEntry));
 | 
			
		||||
        system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                                  sizeof(ExternalRelocationEntry));
 | 
			
		||||
 | 
			
		||||
        ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
 | 
			
		||||
        if (result.IsError()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -815,11 +816,11 @@ ResultCode CROHelper::ResetImportIndexedSymbol() {
 | 
			
		|||
    u32 import_num = GetField(ImportIndexedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < import_num; ++i) {
 | 
			
		||||
        ImportIndexedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        VAddr relocation_addr = entry.relocation_batch_offset;
 | 
			
		||||
        ExternalRelocationEntry relocation_entry;
 | 
			
		||||
        memory.ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                         sizeof(ExternalRelocationEntry));
 | 
			
		||||
        system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                                  sizeof(ExternalRelocationEntry));
 | 
			
		||||
 | 
			
		||||
        ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
 | 
			
		||||
        if (result.IsError()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -836,11 +837,11 @@ ResultCode CROHelper::ResetImportAnonymousSymbol() {
 | 
			
		|||
    u32 import_num = GetField(ImportAnonymousSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < import_num; ++i) {
 | 
			
		||||
        ImportAnonymousSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        VAddr relocation_addr = entry.relocation_batch_offset;
 | 
			
		||||
        ExternalRelocationEntry relocation_entry;
 | 
			
		||||
        memory.ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                         sizeof(ExternalRelocationEntry));
 | 
			
		||||
        system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                                  sizeof(ExternalRelocationEntry));
 | 
			
		||||
 | 
			
		||||
        ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
 | 
			
		||||
        if (result.IsError()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -857,19 +858,20 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
 | 
			
		|||
    u32 import_module_num = GetField(ImportModuleNum);
 | 
			
		||||
    for (u32 i = 0; i < import_module_num; ++i) {
 | 
			
		||||
        ImportModuleEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        std::string want_cro_name = memory.ReadCString(entry.name_offset, import_strings_size);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        std::string want_cro_name =
 | 
			
		||||
            system.Memory().ReadCString(entry.name_offset, import_strings_size);
 | 
			
		||||
 | 
			
		||||
        ResultCode result = ForEachAutoLinkCRO(
 | 
			
		||||
            process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
 | 
			
		||||
            process, system, 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, memory, j, im);
 | 
			
		||||
                        entry.GetImportIndexedSymbolEntry(process, system.Memory(), j, im);
 | 
			
		||||
                        ExportIndexedSymbolEntry ex;
 | 
			
		||||
                        source.GetEntry(memory, im.index, ex);
 | 
			
		||||
                        source.GetEntry(system.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 +886,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, memory, j, im);
 | 
			
		||||
                        entry.GetImportAnonymousSymbolEntry(process, system.Memory(), j, im);
 | 
			
		||||
                        u32 symbol_address = source.SegmentTagToAddress(im.symbol_position);
 | 
			
		||||
                        LOG_TRACE(Service_LDR, "    Imports 0x{:08X}", symbol_address);
 | 
			
		||||
                        ResultCode result =
 | 
			
		||||
| 
						 | 
				
			
			@ -913,15 +915,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(memory, i, entry);
 | 
			
		||||
        target.GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        VAddr relocation_addr = entry.relocation_batch_offset;
 | 
			
		||||
        ExternalRelocationEntry relocation_entry;
 | 
			
		||||
        memory.ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                         sizeof(ExternalRelocationEntry));
 | 
			
		||||
        system.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);
 | 
			
		||||
                system.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 +946,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(memory, i, entry);
 | 
			
		||||
        target.GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        VAddr relocation_addr = entry.relocation_batch_offset;
 | 
			
		||||
        ExternalRelocationEntry relocation_entry;
 | 
			
		||||
        memory.ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                         sizeof(ExternalRelocationEntry));
 | 
			
		||||
        system.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);
 | 
			
		||||
                system.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 +976,19 @@ 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(memory, i, entry);
 | 
			
		||||
        target.GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name)
 | 
			
		||||
        if (system.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, memory, j, im);
 | 
			
		||||
            entry.GetImportIndexedSymbolEntry(process, system.Memory(), j, im);
 | 
			
		||||
            ExportIndexedSymbolEntry ex;
 | 
			
		||||
            GetEntry(memory, im.index, ex);
 | 
			
		||||
            GetEntry(system.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 +1003,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, memory, j, im);
 | 
			
		||||
            entry.GetImportAnonymousSymbolEntry(process, system.Memory(), j, im);
 | 
			
		||||
            u32 symbol_address = SegmentTagToAddress(im.symbol_position);
 | 
			
		||||
            LOG_TRACE(Service_LDR, "    exports symbol 0x{:08X}", symbol_address);
 | 
			
		||||
            ResultCode result =
 | 
			
		||||
| 
						 | 
				
			
			@ -1023,16 +1026,17 @@ 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(memory, i, entry);
 | 
			
		||||
        target.GetEntry(system.Memory(), i, entry);
 | 
			
		||||
 | 
			
		||||
        if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name)
 | 
			
		||||
        if (system.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, memory, j, im);
 | 
			
		||||
            entry.GetImportIndexedSymbolEntry(process, system.Memory(), j, im);
 | 
			
		||||
            ResultCode result =
 | 
			
		||||
                target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
 | 
			
		||||
            if (result.IsError()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1045,7 +1049,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
 | 
			
		|||
                  target.ModuleName());
 | 
			
		||||
        for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
 | 
			
		||||
            ImportAnonymousSymbolEntry im;
 | 
			
		||||
            entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
 | 
			
		||||
            entry.GetImportAnonymousSymbolEntry(process, system.Memory(), j, im);
 | 
			
		||||
            ResultCode result =
 | 
			
		||||
                target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
 | 
			
		||||
            if (result.IsError()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1063,15 +1067,16 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
 | 
			
		|||
    u32 symbol_import_num = GetField(ImportNamedSymbolNum);
 | 
			
		||||
    for (u32 i = 0; i < symbol_import_num; ++i) {
 | 
			
		||||
        ImportNamedSymbolEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.Memory(), i, entry);
 | 
			
		||||
        VAddr relocation_addr = entry.relocation_batch_offset;
 | 
			
		||||
        ExternalRelocationEntry relocation_entry;
 | 
			
		||||
        memory.ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                         sizeof(ExternalRelocationEntry));
 | 
			
		||||
        system.Memory().ReadBlock(process, relocation_addr, &relocation_entry,
 | 
			
		||||
                                  sizeof(ExternalRelocationEntry));
 | 
			
		||||
 | 
			
		||||
        if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
 | 
			
		||||
        if (system.Memory().ReadCString(entry.name_offset, import_strings_size) ==
 | 
			
		||||
            "__aeabi_atexit") {
 | 
			
		||||
            ResultCode result = ForEachAutoLinkCRO(
 | 
			
		||||
                process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
 | 
			
		||||
                process, system, crs_address, [&](CROHelper source) -> ResultVal<bool> {
 | 
			
		||||
                    u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_");
 | 
			
		||||
 | 
			
		||||
                    if (symbol_address != 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1126,7 +1131,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
 | 
			
		|||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result = VerifyStringTableLength(memory, GetField(ModuleNameOffset), GetField(ModuleNameSize));
 | 
			
		||||
    result = VerifyStringTableLength(system.Memory(), GetField(ModuleNameOffset),
 | 
			
		||||
                                     GetField(ModuleNameSize));
 | 
			
		||||
    if (result.IsError()) {
 | 
			
		||||
        LOG_ERROR(Service_LDR, "Error verifying module name {:08X}", result.raw);
 | 
			
		||||
        return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -1155,8 +1161,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
 | 
			
		|||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result =
 | 
			
		||||
        VerifyStringTableLength(memory, GetField(ExportStringsOffset), GetField(ExportStringsSize));
 | 
			
		||||
    result = VerifyStringTableLength(system.Memory(), GetField(ExportStringsOffset),
 | 
			
		||||
                                     GetField(ExportStringsSize));
 | 
			
		||||
    if (result.IsError()) {
 | 
			
		||||
        LOG_ERROR(Service_LDR, "Error verifying export strings {:08X}", result.raw);
 | 
			
		||||
        return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -1192,8 +1198,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment
 | 
			
		|||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result =
 | 
			
		||||
        VerifyStringTableLength(memory, GetField(ImportStringsOffset), GetField(ImportStringsSize));
 | 
			
		||||
    result = VerifyStringTableLength(system.Memory(), GetField(ImportStringsOffset),
 | 
			
		||||
                                     GetField(ImportStringsSize));
 | 
			
		||||
    if (result.IsError()) {
 | 
			
		||||
        LOG_ERROR(Service_LDR, "Error verifying import strings {:08X}", result.raw);
 | 
			
		||||
        return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -1266,11 +1272,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(memory, 2, entry);
 | 
			
		||||
                GetEntry(system.Memory(), 2, entry);
 | 
			
		||||
                ASSERT(entry.type == SegmentType::Data);
 | 
			
		||||
                data_segment_address = entry.offset;
 | 
			
		||||
                entry.offset = GetField(DataOffset);
 | 
			
		||||
                SetEntry(memory, 2, entry);
 | 
			
		||||
                SetEntry(system.Memory(), 2, entry);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        SCOPE_EXIT({
 | 
			
		||||
| 
						 | 
				
			
			@ -1278,9 +1284,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(memory, 2, entry);
 | 
			
		||||
                    GetEntry(system.Memory(), 2, entry);
 | 
			
		||||
                    entry.offset = data_segment_address;
 | 
			
		||||
                    SetEntry(memory, 2, entry);
 | 
			
		||||
                    SetEntry(system.Memory(), 2, entry);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			@ -1301,7 +1307,7 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Exports symbols to other modules
 | 
			
		||||
    result = ForEachAutoLinkCRO(process, memory, cpu, crs_address,
 | 
			
		||||
    result = ForEachAutoLinkCRO(process, system, crs_address,
 | 
			
		||||
                                [this](CROHelper target) -> ResultVal<bool> {
 | 
			
		||||
                                    ResultCode result = ApplyExportNamedSymbol(target);
 | 
			
		||||
                                    if (result.IsError())
 | 
			
		||||
| 
						 | 
				
			
			@ -1346,7 +1352,7 @@ 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, memory, cpu, crs_address,
 | 
			
		||||
    result = ForEachAutoLinkCRO(process, system, crs_address,
 | 
			
		||||
                                [this](CROHelper target) -> ResultVal<bool> {
 | 
			
		||||
                                    ResultCode result = ResetExportNamedSymbol(target);
 | 
			
		||||
                                    if (result.IsError())
 | 
			
		||||
| 
						 | 
				
			
			@ -1387,13 +1393,13 @@ void CROHelper::InitCRS() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void CROHelper::Register(VAddr crs_address, bool auto_link) {
 | 
			
		||||
    CROHelper crs(crs_address, process, memory, cpu);
 | 
			
		||||
    CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process, memory, cpu);
 | 
			
		||||
    CROHelper crs(crs_address, process, system);
 | 
			
		||||
    CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process, system);
 | 
			
		||||
 | 
			
		||||
    if (head.module_address) {
 | 
			
		||||
        // there are already CROs registered
 | 
			
		||||
        // register as the new tail
 | 
			
		||||
        CROHelper tail(head.PreviousModule(), process, memory, cpu);
 | 
			
		||||
        CROHelper tail(head.PreviousModule(), process, system);
 | 
			
		||||
 | 
			
		||||
        // link with the old tail
 | 
			
		||||
        ASSERT(tail.NextModule() == 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -1419,11 +1425,11 @@ void CROHelper::Register(VAddr crs_address, bool auto_link) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void CROHelper::Unregister(VAddr crs_address) {
 | 
			
		||||
    CROHelper crs(crs_address, process, memory, cpu);
 | 
			
		||||
    CROHelper next_head(crs.NextModule(), process, memory, cpu);
 | 
			
		||||
    CROHelper previous_head(crs.PreviousModule(), process, memory, cpu);
 | 
			
		||||
    CROHelper next(NextModule(), process, memory, cpu);
 | 
			
		||||
    CROHelper previous(PreviousModule(), process, memory, cpu);
 | 
			
		||||
    CROHelper crs(crs_address, process, system);
 | 
			
		||||
    CROHelper next_head(crs.NextModule(), process, system);
 | 
			
		||||
    CROHelper previous_head(crs.PreviousModule(), process, system);
 | 
			
		||||
    CROHelper next(NextModule(), process, system);
 | 
			
		||||
    CROHelper previous(PreviousModule(), process, system);
 | 
			
		||||
 | 
			
		||||
    if (module_address == next_head.module_address ||
 | 
			
		||||
        module_address == previous_head.module_address) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1517,7 +1523,7 @@ std::tuple<VAddr, u32> CROHelper::GetExecutablePages() const {
 | 
			
		|||
    u32 segment_num = GetField(SegmentNum);
 | 
			
		||||
    for (u32 i = 0; i < segment_num; ++i) {
 | 
			
		||||
        SegmentEntry entry;
 | 
			
		||||
        GetEntry(memory, i, entry);
 | 
			
		||||
        GetEntry(system.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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,12 +33,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, Memory::MemorySystem& memory,
 | 
			
		||||
                       ARM_Interface& cpu)
 | 
			
		||||
        : module_address(cro_address), process(process), memory(memory), cpu(cpu) {}
 | 
			
		||||
    explicit CROHelper(VAddr cro_address, Kernel::Process& process, Core::System& system)
 | 
			
		||||
        : module_address(cro_address), process(process), system(system) {}
 | 
			
		||||
 | 
			
		||||
    std::string ModuleName() const {
 | 
			
		||||
        return memory.ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
 | 
			
		||||
        return system.Memory().ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    u32 GetFileSize() const {
 | 
			
		||||
| 
						 | 
				
			
			@ -144,8 +143,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;
 | 
			
		||||
    ARM_Interface& cpu;
 | 
			
		||||
    Core::System& system;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Each item in this enum represents a u32 field in the header begin from address+0x80,
 | 
			
		||||
| 
						 | 
				
			
			@ -403,11 +401,11 @@ private:
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    u32 GetField(HeaderField field) const {
 | 
			
		||||
        return memory.Read32(Field(field));
 | 
			
		||||
        return system.Memory().Read32(Field(field));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetField(HeaderField field, u32 value) {
 | 
			
		||||
        memory.Write32(Field(field), value);
 | 
			
		||||
        system.Memory().Write32(Field(field), value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -474,12 +472,11 @@ private:
 | 
			
		|||
     *         otherwise error code of the last iteration.
 | 
			
		||||
     */
 | 
			
		||||
    template <typename FunctionObject>
 | 
			
		||||
    static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, Memory::MemorySystem& memory,
 | 
			
		||||
                                         ARM_Interface& cpu, VAddr crs_address,
 | 
			
		||||
                                         FunctionObject func) {
 | 
			
		||||
    static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, Core::System& system,
 | 
			
		||||
                                         VAddr crs_address, FunctionObject func) {
 | 
			
		||||
        VAddr current = crs_address;
 | 
			
		||||
        while (current != 0) {
 | 
			
		||||
            CROHelper cro(current, process, memory, cpu);
 | 
			
		||||
            CROHelper cro(current, process, system);
 | 
			
		||||
            CASCADE_RESULT(bool next, func(cro));
 | 
			
		||||
            if (!next)
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) {
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CROHelper crs(crs_address, *process, system.Memory(), system.CPU());
 | 
			
		||||
    CROHelper crs(crs_address, *process, system);
 | 
			
		||||
    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, system.Memory(), system.CPU());
 | 
			
		||||
    CROHelper cro(cro_address, *process, system);
 | 
			
		||||
 | 
			
		||||
    result = cro.VerifyHash(cro_size, crr_address);
 | 
			
		||||
    if (result.IsError()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -313,7 +313,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    system.CPU().InvalidateCacheRange(cro_address, cro_size);
 | 
			
		||||
    system.InvalidateCacheRange(cro_address, cro_size);
 | 
			
		||||
 | 
			
		||||
    LOG_INFO(Service_LDR, "CRO \"{}\" loaded at 0x{:08X}, fixed_end=0x{:08X}", cro.ModuleName(),
 | 
			
		||||
             cro_address, cro_address + fix_size);
 | 
			
		||||
| 
						 | 
				
			
			@ -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, system.Memory(), system.CPU());
 | 
			
		||||
    CROHelper cro(cro_address, *process, system);
 | 
			
		||||
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -386,7 +386,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) {
 | 
			
		|||
        LOG_ERROR(Service_LDR, "Error unmapping CRO {:08X}", result.raw);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    system.CPU().InvalidateCacheRange(cro_address, fixed_size);
 | 
			
		||||
    system.InvalidateCacheRange(cro_address, fixed_size);
 | 
			
		||||
 | 
			
		||||
    rb.Push(result);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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, system.Memory(), system.CPU());
 | 
			
		||||
    CROHelper cro(cro_address, *process, system);
 | 
			
		||||
 | 
			
		||||
    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, system.Memory(), system.CPU());
 | 
			
		||||
    CROHelper cro(cro_address, *process, system);
 | 
			
		||||
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -487,7 +487,7 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) {
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CROHelper crs(slot->loaded_crs, *process, system.Memory(), system.CPU());
 | 
			
		||||
    CROHelper crs(slot->loaded_crs, *process, system);
 | 
			
		||||
    crs.Unrebase(true);
 | 
			
		||||
 | 
			
		||||
    ResultCode result = RESULT_SUCCESS;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue