diff options
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> | 2016-09-18 02:38:01 +0200 |
---|---|---|
committer | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> | 2016-09-18 02:38:01 +0200 |
commit | dc8479928c5aee4c6ad6fe4f59006fb604cee701 (patch) | |
tree | 569a7f13128450bbab973236615587ff00bced5f /src/core/hle/service/ldr_ro | |
parent | Travis: Import Dolphin’s clang-format hook. (diff) | |
download | yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.gz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.bz2 yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.lz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.xz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.zst yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.zip |
Diffstat (limited to 'src/core/hle/service/ldr_ro')
-rw-r--r-- | src/core/hle/service/ldr_ro/cro_helper.cpp | 375 | ||||
-rw-r--r-- | src/core/hle/service/ldr_ro/cro_helper.h | 145 | ||||
-rw-r--r-- | src/core/hle/service/ldr_ro/ldr_ro.cpp | 208 | ||||
-rw-r--r-- | src/core/hle/service/ldr_ro/memory_synchronizer.cpp | 5 |
4 files changed, 399 insertions, 334 deletions
diff --git a/src/core/hle/service/ldr_ro/cro_helper.cpp b/src/core/hle/service/ldr_ro/cro_helper.cpp index 3d2a613ee..5757a4e64 100644 --- a/src/core/hle/service/ldr_ro/cro_helper.cpp +++ b/src/core/hle/service/ldr_ro/cro_helper.cpp @@ -14,38 +14,29 @@ namespace LDR_RO { static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F - ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, + ErrorLevel::Usage); static ResultCode CROFormatError(u32 description) { - return ResultCode(static_cast<ErrorDescription>(description), ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); + return ResultCode(static_cast<ErrorDescription>(description), ErrorModule::RO, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); } -const std::array<int, 17> CROHelper::ENTRY_SIZE {{ - 1, // code - 1, // data - 1, // module name - sizeof(SegmentEntry), - sizeof(ExportNamedSymbolEntry), - sizeof(ExportIndexedSymbolEntry), - 1, // export strings - sizeof(ExportTreeEntry), - sizeof(ImportModuleEntry), - sizeof(ExternalRelocationEntry), - sizeof(ImportNamedSymbolEntry), - sizeof(ImportIndexedSymbolEntry), - sizeof(ImportAnonymousSymbolEntry), - 1, // import strings - sizeof(StaticAnonymousSymbolEntry), - sizeof(InternalRelocationEntry), - sizeof(StaticRelocationEntry) -}}; - -const std::array<CROHelper::HeaderField, 4> CROHelper::FIX_BARRIERS {{ - Fix0Barrier, - Fix1Barrier, - Fix2Barrier, - Fix3Barrier -}}; +const std::array<int, 17> CROHelper::ENTRY_SIZE{ + {1, // code + 1, // data + 1, // module name + sizeof(SegmentEntry), sizeof(ExportNamedSymbolEntry), sizeof(ExportIndexedSymbolEntry), + 1, // export strings + sizeof(ExportTreeEntry), sizeof(ImportModuleEntry), sizeof(ExternalRelocationEntry), + sizeof(ImportNamedSymbolEntry), sizeof(ImportIndexedSymbolEntry), + sizeof(ImportAnonymousSymbolEntry), + 1, // import strings + sizeof(StaticAnonymousSymbolEntry), sizeof(InternalRelocationEntry), + sizeof(StaticRelocationEntry)}}; + +const std::array<CROHelper::HeaderField, 4> CROHelper::FIX_BARRIERS{ + {Fix0Barrier, Fix1Barrier, Fix2Barrier, Fix3Barrier}}; VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const { u32 segment_num = GetField(SegmentNum); @@ -63,7 +54,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const { } ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType relocation_type, - u32 addend, u32 symbol_address, u32 target_future_address) { + u32 addend, u32 symbol_address, u32 target_future_address) { switch (relocation_type) { case RelocationType::Nothing: @@ -124,7 +115,8 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool return CROFormatError(0x12); } - ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, symbol_address, relocation_target); + ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, + symbol_address, relocation_target); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); return result; @@ -167,7 +159,7 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const { if (test_byte >= len) { next.raw = entry.left.raw; - } else if((name[test_byte] >> test_bit_in_byte) & 1) { + } else if ((name[test_byte] >> test_bit_in_byte) & 1) { next.raw = entry.right.raw; } else { next.raw = entry.left.raw; @@ -212,26 +204,13 @@ ResultCode CROHelper::RebaseHeader(u32 cro_size) { return error; // verifies that all offsets are in the correct order - constexpr std::array<HeaderField, 18> OFFSET_ORDER = {{ - CodeOffset, - ModuleNameOffset, - SegmentTableOffset, - ExportNamedSymbolTableOffset, - ExportTreeTableOffset, - ExportIndexedSymbolTableOffset, - ExportStringsOffset, - ImportModuleTableOffset, - ExternalRelocationTableOffset, - ImportNamedSymbolTableOffset, - ImportIndexedSymbolTableOffset, - ImportAnonymousSymbolTableOffset, - ImportStringsOffset, - StaticAnonymousSymbolTableOffset, - InternalRelocationTableOffset, - StaticRelocationTableOffset, - DataOffset, - FileSize - }}; + constexpr std::array<HeaderField, 18> OFFSET_ORDER = { + {CodeOffset, ModuleNameOffset, SegmentTableOffset, ExportNamedSymbolTableOffset, + ExportTreeTableOffset, ExportIndexedSymbolTableOffset, ExportStringsOffset, + ImportModuleTableOffset, ExternalRelocationTableOffset, ImportNamedSymbolTableOffset, + ImportIndexedSymbolTableOffset, ImportAnonymousSymbolTableOffset, ImportStringsOffset, + StaticAnonymousSymbolTableOffset, InternalRelocationTableOffset, + StaticRelocationTableOffset, DataOffset, FileSize}}; u32 prev_offset = GetField(OFFSET_ORDER[0]); u32 cur_offset; @@ -266,9 +245,9 @@ ResultCode CROHelper::RebaseHeader(u32 cro_size) { return RESULT_SUCCESS; } -ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, - VAddr data_segment_address, u32 data_segment_size, - VAddr bss_segment_address, u32 bss_segment_size) { +ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_address, + u32 data_segment_size, VAddr bss_segment_address, + u32 bss_segment_size) { u32 prev_data_segment = 0; u32 segment_num = GetField(SegmentNum); @@ -309,8 +288,8 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() { if (entry.name_offset != 0) { entry.name_offset += module_address; - if (entry.name_offset < export_strings_offset - || entry.name_offset >= export_strings_end) { + if (entry.name_offset < export_strings_offset || + entry.name_offset >= export_strings_end) { return CROFormatError(0x11); } } @@ -337,9 +316,13 @@ ResultCode CROHelper::RebaseImportModuleTable() { VAddr import_strings_offset = GetField(ImportStringsOffset); VAddr import_strings_end = import_strings_offset + GetField(ImportStringsSize); VAddr import_indexed_symbol_table_offset = GetField(ImportIndexedSymbolTableOffset); - VAddr index_import_table_end = import_indexed_symbol_table_offset + GetField(ImportIndexedSymbolNum) * sizeof(ImportIndexedSymbolEntry); + VAddr index_import_table_end = + import_indexed_symbol_table_offset + + GetField(ImportIndexedSymbolNum) * sizeof(ImportIndexedSymbolEntry); VAddr import_anonymous_symbol_table_offset = GetField(ImportAnonymousSymbolTableOffset); - VAddr offset_import_table_end = import_anonymous_symbol_table_offset + GetField(ImportAnonymousSymbolNum) * sizeof(ImportAnonymousSymbolEntry); + VAddr offset_import_table_end = + import_anonymous_symbol_table_offset + + GetField(ImportAnonymousSymbolNum) * sizeof(ImportAnonymousSymbolEntry); u32 module_num = GetField(ImportModuleNum); for (u32 i = 0; i < module_num; ++i) { @@ -348,24 +331,24 @@ ResultCode CROHelper::RebaseImportModuleTable() { if (entry.name_offset != 0) { entry.name_offset += module_address; - if (entry.name_offset < import_strings_offset - || entry.name_offset >= import_strings_end) { + if (entry.name_offset < import_strings_offset || + entry.name_offset >= import_strings_end) { return CROFormatError(0x18); } } if (entry.import_indexed_symbol_table_offset != 0) { entry.import_indexed_symbol_table_offset += module_address; - if (entry.import_indexed_symbol_table_offset < import_indexed_symbol_table_offset - || entry.import_indexed_symbol_table_offset > index_import_table_end) { + if (entry.import_indexed_symbol_table_offset < import_indexed_symbol_table_offset || + entry.import_indexed_symbol_table_offset > index_import_table_end) { return CROFormatError(0x18); } } if (entry.import_anonymous_symbol_table_offset != 0) { entry.import_anonymous_symbol_table_offset += module_address; - if (entry.import_anonymous_symbol_table_offset < import_anonymous_symbol_table_offset - || entry.import_anonymous_symbol_table_offset > offset_import_table_end) { + if (entry.import_anonymous_symbol_table_offset < import_anonymous_symbol_table_offset || + entry.import_anonymous_symbol_table_offset > offset_import_table_end) { return CROFormatError(0x18); } } @@ -379,25 +362,27 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() { VAddr import_strings_offset = GetField(ImportStringsOffset); VAddr import_strings_end = import_strings_offset + GetField(ImportStringsSize); VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); - VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); + VAddr external_relocation_table_end = + external_relocation_table_offset + + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); u32 num = GetField(ImportNamedSymbolNum); - for (u32 i = 0; i < num ; ++i) { + for (u32 i = 0; i < num; ++i) { ImportNamedSymbolEntry entry; GetEntry(i, entry); if (entry.name_offset != 0) { entry.name_offset += module_address; - if (entry.name_offset < import_strings_offset - || entry.name_offset >= import_strings_end) { + if (entry.name_offset < import_strings_offset || + entry.name_offset >= import_strings_end) { return CROFormatError(0x1B); } } if (entry.relocation_batch_offset != 0) { entry.relocation_batch_offset += module_address; - if (entry.relocation_batch_offset < external_relocation_table_offset - || entry.relocation_batch_offset > external_relocation_table_end) { + if (entry.relocation_batch_offset < external_relocation_table_offset || + entry.relocation_batch_offset > external_relocation_table_end) { return CROFormatError(0x1B); } } @@ -409,17 +394,19 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() { ResultCode CROHelper::RebaseImportIndexedSymbolTable() { VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); - VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); + VAddr external_relocation_table_end = + external_relocation_table_offset + + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); u32 num = GetField(ImportIndexedSymbolNum); - for (u32 i = 0; i < num ; ++i) { + for (u32 i = 0; i < num; ++i) { ImportIndexedSymbolEntry entry; GetEntry(i, entry); if (entry.relocation_batch_offset != 0) { entry.relocation_batch_offset += module_address; - if (entry.relocation_batch_offset < external_relocation_table_offset - || entry.relocation_batch_offset > external_relocation_table_end) { + if (entry.relocation_batch_offset < external_relocation_table_offset || + entry.relocation_batch_offset > external_relocation_table_end) { return CROFormatError(0x14); } } @@ -431,17 +418,19 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() { ResultCode CROHelper::RebaseImportAnonymousSymbolTable() { VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); - VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); + VAddr external_relocation_table_end = + external_relocation_table_offset + + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); u32 num = GetField(ImportAnonymousSymbolNum); - for (u32 i = 0; i < num ; ++i) { + for (u32 i = 0; i < num; ++i) { ImportAnonymousSymbolEntry entry; GetEntry(i, entry); if (entry.relocation_batch_offset != 0) { entry.relocation_batch_offset += module_address; - if (entry.relocation_batch_offset < external_relocation_table_offset - || entry.relocation_batch_offset > external_relocation_table_end) { + if (entry.relocation_batch_offset < external_relocation_table_offset || + entry.relocation_batch_offset > external_relocation_table_end) { return CROFormatError(0x17); } } @@ -475,7 +464,8 @@ ResultCode CROHelper::ResetExternalRelocations() { return CROFormatError(0x12); } - ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, unresolved_symbol, relocation_target); + ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, + unresolved_symbol, relocation_target); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); return result; @@ -528,23 +518,27 @@ ResultCode CROHelper::ClearExternalRelocations() { ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) { VAddr static_relocation_table_offset = GetField(StaticRelocationTableOffset); - VAddr static_relocation_table_end = static_relocation_table_offset + GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry); + VAddr static_relocation_table_end = + static_relocation_table_offset + + GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry); CROHelper crs(crs_address); u32 offset_export_num = GetField(StaticAnonymousSymbolNum); - LOG_INFO(Service_LDR, "CRO \"%s\" exports %d static anonymous symbols", ModuleName().data(), offset_export_num); + LOG_INFO(Service_LDR, "CRO \"%s\" exports %d static anonymous symbols", ModuleName().data(), + offset_export_num); for (u32 i = 0; i < offset_export_num; ++i) { StaticAnonymousSymbolEntry entry; GetEntry(i, entry); u32 batch_address = entry.relocation_batch_offset + module_address; - if (batch_address < static_relocation_table_offset - || batch_address > static_relocation_table_end) { + if (batch_address < static_relocation_table_offset || + batch_address > static_relocation_table_end) { return CROFormatError(0x16); } u32 symbol_address = SegmentTagToAddress(entry.symbol_position); - LOG_TRACE(Service_LDR, "CRO \"%s\" exports 0x%08X to the static module", ModuleName().data(), symbol_address); + LOG_TRACE(Service_LDR, "CRO \"%s\" exports 0x%08X to the static module", + ModuleName().data(), symbol_address); ResultCode result = crs.ApplyRelocationBatch(batch_address, symbol_address); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); @@ -571,7 +565,8 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) { if (target_segment.type == SegmentType::Data) { // If the relocation is to the .data segment, we need to relocate it in the old buffer - target_address = old_data_segment_address + relocation.target_position.offset_into_segment; + target_address = + old_data_segment_address + relocation.target_position.offset_into_segment; } else { target_address = target_addressB; } @@ -582,8 +577,10 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) { SegmentEntry symbol_segment; GetEntry(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, symbol_segment.offset, target_addressB); + 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, + symbol_segment.offset, target_addressB); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); return result; @@ -734,25 +731,29 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) { Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); if (!relocation_entry.is_batch_resolved) { - ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { - std::string symbol_name = Memory::ReadCString(entry.name_offset, import_strings_size); - u32 symbol_address = source.FindExportNamedSymbol(symbol_name); - - if (symbol_address != 0) { - LOG_TRACE(Service_LDR, "CRO \"%s\" imports \"%s\" from \"%s\"", - ModuleName().data(), symbol_name.data(), source.ModuleName().data()); - - ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); - if (result.IsError()) { - LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); - return result; + ResultCode result = + ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { + std::string symbol_name = + Memory::ReadCString(entry.name_offset, import_strings_size); + u32 symbol_address = source.FindExportNamedSymbol(symbol_name); + + if (symbol_address != 0) { + LOG_TRACE(Service_LDR, "CRO \"%s\" imports \"%s\" from \"%s\"", + ModuleName().data(), symbol_name.data(), + source.ModuleName().data()); + + ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); + if (result.IsError()) { + LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", + result.raw); + return result; + } + + return MakeResult<bool>(false); } - return MakeResult<bool>(false); - } - - return MakeResult<bool>(true); - }); + return MakeResult<bool>(true); + }); if (result.IsError()) { return result; } @@ -777,7 +778,6 @@ ResultCode CROHelper::ResetImportNamedSymbol() { LOG_ERROR(Service_LDR, "Error reseting relocation batch %08X", result.raw); return result; } - } return RESULT_SUCCESS; } @@ -831,40 +831,47 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) { GetEntry(i, entry); std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size); - ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { - if (want_cro_name == source.ModuleName()) { - LOG_INFO(Service_LDR, "CRO \"%s\" imports %d indexed symbols from \"%s\"", - ModuleName().data(), entry.import_indexed_symbol_num, source.ModuleName().data()); - for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { - ImportIndexedSymbolEntry im; - entry.GetImportIndexedSymbolEntry(j, im); - ExportIndexedSymbolEntry ex; - source.GetEntry(im.index, ex); - u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position); - LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); - ResultCode result = ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); - if (result.IsError()) { - LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); - return result; + ResultCode result = + ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { + if (want_cro_name == source.ModuleName()) { + LOG_INFO(Service_LDR, "CRO \"%s\" imports %d indexed symbols from \"%s\"", + ModuleName().data(), entry.import_indexed_symbol_num, + source.ModuleName().data()); + for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { + ImportIndexedSymbolEntry im; + entry.GetImportIndexedSymbolEntry(j, im); + ExportIndexedSymbolEntry ex; + source.GetEntry(im.index, ex); + u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position); + LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); + ResultCode result = + ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); + if (result.IsError()) { + LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", + result.raw); + return result; + } } - } - LOG_INFO(Service_LDR, "CRO \"%s\" imports %d anonymous symbols from \"%s\"", - ModuleName().data(), entry.import_anonymous_symbol_num, source.ModuleName().data()); - for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { - ImportAnonymousSymbolEntry im; - entry.GetImportAnonymousSymbolEntry(j, im); - u32 symbol_address = source.SegmentTagToAddress(im.symbol_position); - LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); - ResultCode result = ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); - if (result.IsError()) { - LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); - return result; + LOG_INFO(Service_LDR, "CRO \"%s\" imports %d anonymous symbols from \"%s\"", + ModuleName().data(), entry.import_anonymous_symbol_num, + source.ModuleName().data()); + for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { + ImportAnonymousSymbolEntry im; + entry.GetImportAnonymousSymbolEntry(j, im); + u32 symbol_address = source.SegmentTagToAddress(im.symbol_position); + LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); + ResultCode result = + ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); + if (result.IsError()) { + LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", + result.raw); + return result; + } } + return MakeResult<bool>(false); } - return MakeResult<bool>(false); - } - return MakeResult<bool>(true); - }); + return MakeResult<bool>(true); + }); if (result.IsError()) { return result; } @@ -873,8 +880,8 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) { } ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { - LOG_DEBUG(Service_LDR, "CRO \"%s\" exports named symbols to \"%s\"", - ModuleName().data(), target.ModuleName().data()); + LOG_DEBUG(Service_LDR, "CRO \"%s\" exports named symbols to \"%s\"", ModuleName().data(), + target.ModuleName().data()); u32 target_import_strings_size = target.GetField(ImportStringsSize); u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum); for (u32 i = 0; i < target_symbol_import_num; ++i) { @@ -885,7 +892,8 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { Memory::ReadBlock(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); + std::string symbol_name = + 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 \"%s\"", symbol_name.data()); @@ -901,8 +909,8 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { } ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) { - LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports named symbols to \"%s\"", - ModuleName().data(), target.ModuleName().data()); + LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports named symbols to \"%s\"", ModuleName().data(), + target.ModuleName().data()); u32 unresolved_symbol = target.GetOnUnresolvedAddress(); u32 target_import_strings_size = target.GetField(ImportStringsSize); u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum); @@ -914,11 +922,13 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) { Memory::ReadBlock(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); + std::string symbol_name = + 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 \"%s\"", symbol_name.data()); - ResultCode result = target.ApplyRelocationBatch(relocation_addr, unresolved_symbol, true); + ResultCode result = + target.ApplyRelocationBatch(relocation_addr, unresolved_symbol, true); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -940,8 +950,8 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) { if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) continue; - LOG_INFO(Service_LDR, "CRO \"%s\" exports %d indexed symbols to \"%s\"", - module_name.data(), entry.import_indexed_symbol_num, target.ModuleName().data()); + LOG_INFO(Service_LDR, "CRO \"%s\" exports %d indexed symbols to \"%s\"", module_name.data(), + entry.import_indexed_symbol_num, target.ModuleName().data()); for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { ImportIndexedSymbolEntry im; entry.GetImportIndexedSymbolEntry(j, im); @@ -949,7 +959,8 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) { GetEntry(im.index, ex); u32 symbol_address = SegmentTagToAddress(ex.symbol_position); LOG_TRACE(Service_LDR, " exports symbol 0x%08X", symbol_address); - ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); + ResultCode result = + target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -957,13 +968,14 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) { } LOG_INFO(Service_LDR, "CRO \"%s\" exports %d anonymous symbols to \"%s\"", - module_name.data(), entry.import_anonymous_symbol_num, target.ModuleName().data()); + module_name.data(), entry.import_anonymous_symbol_num, target.ModuleName().data()); for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { ImportAnonymousSymbolEntry im; entry.GetImportAnonymousSymbolEntry(j, im); u32 symbol_address = SegmentTagToAddress(im.symbol_position); LOG_TRACE(Service_LDR, " exports symbol 0x%08X", symbol_address); - ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); + ResultCode result = + target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -987,12 +999,13 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) { if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) continue; - LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports indexed symbols to \"%s\"", - module_name.data(), target.ModuleName().data()); + LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports indexed symbols to \"%s\"", module_name.data(), + target.ModuleName().data()); for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { ImportIndexedSymbolEntry im; entry.GetImportIndexedSymbolEntry(j, im); - ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); + ResultCode result = + target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -1000,11 +1013,12 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) { } LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports anonymous symbols to \"%s\"", - module_name.data(), target.ModuleName().data()); + module_name.data(), target.ModuleName().data()); for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { ImportAnonymousSymbolEntry im; entry.GetImportAnonymousSymbolEntry(j, im); - ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); + ResultCode result = + target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -1025,25 +1039,27 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) { ExternalRelocationEntry relocation_entry; Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); - if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit"){ - ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { - u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); + if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") { + ResultCode result = + ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { + u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); - if (symbol_address != 0) { - LOG_DEBUG(Service_LDR, "CRO \"%s\" import exit function from \"%s\"", - ModuleName().data(), source.ModuleName().data()); + if (symbol_address != 0) { + LOG_DEBUG(Service_LDR, "CRO \"%s\" import exit function from \"%s\"", + ModuleName().data(), source.ModuleName().data()); - ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); - if (result.IsError()) { - LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); - return result; - } + ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); + if (result.IsError()) { + LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", + result.raw); + return result; + } - return MakeResult<bool>(false); - } + return MakeResult<bool>(false); + } - return MakeResult<bool>(true); - }); + return MakeResult<bool>(true); + }); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying exit relocation %08X", result.raw); return result; @@ -1070,9 +1086,9 @@ static ResultCode VerifyStringTableLength(VAddr address, u32 size) { return RESULT_SUCCESS; } -ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, - VAddr data_segment_addresss, u32 data_segment_size, - VAddr bss_segment_address, u32 bss_segment_size, bool is_crs) { +ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment_addresss, + u32 data_segment_size, VAddr bss_segment_address, u32 bss_segment_size, + bool is_crs) { ResultCode result = RebaseHeader(cro_size); if (result.IsError()) { @@ -1088,9 +1104,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, u32 prev_data_segment_address = 0; if (!is_crs) { - auto result_val = RebaseSegmentTable(cro_size, - data_segment_addresss, data_segment_size, - bss_segment_address, bss_segment_size); + auto result_val = RebaseSegmentTable(cro_size, data_segment_addresss, data_segment_size, + bss_segment_address, bss_segment_size); if (result_val.Failed()) { LOG_ERROR(Service_LDR, "Error rebasing segment table %08X", result_val.Code().raw); return result_val.Code(); @@ -1374,7 +1389,8 @@ void CROHelper::Unregister(VAddr crs_address) { CROHelper next_head(crs.NextModule()), previous_head(crs.PreviousModule()); CROHelper next(NextModule()), previous(PreviousModule()); - if (module_address == next_head.module_address || module_address == previous_head.module_address) { + if (module_address == next_head.module_address || + module_address == previous_head.module_address) { // removing head if (next.module_address) { // the next is new head @@ -1400,7 +1416,8 @@ void CROHelper::Unregister(VAddr crs_address) { // let head's previous point to the new tail if (next_head.module_address && next_head.PreviousModule() == module_address) { next_head.SetPreviousModule(previous.module_address); - } else if (previous_head.module_address && previous_head.PreviousModule() == module_address) { + } else if (previous_head.module_address && + previous_head.PreviousModule() == module_address) { previous_head.SetPreviousModule(previous.module_address); } else { UNREACHABLE(); @@ -1419,9 +1436,9 @@ u32 CROHelper::GetFixEnd(u32 fix_level) const { u32 entry_size_i = 2; int field = ModuleNameOffset; while (true) { - end = std::max<u32>(end, - GetField(static_cast<HeaderField>(field)) + - GetField(static_cast<HeaderField>(field + 1)) * ENTRY_SIZE[entry_size_i]); + end = std::max<u32>(end, GetField(static_cast<HeaderField>(field)) + + GetField(static_cast<HeaderField>(field + 1)) * + ENTRY_SIZE[entry_size_i]); ++entry_size_i; field += 2; diff --git a/src/core/hle/service/ldr_ro/cro_helper.h b/src/core/hle/service/ldr_ro/cro_helper.h index 34e357afd..e4457d4be 100644 --- a/src/core/hle/service/ldr_ro/cro_helper.h +++ b/src/core/hle/service/ldr_ro/cro_helper.h @@ -10,8 +10,8 @@ #include "common/common_types.h" #include "common/swap.h" -#include "core/memory.h" #include "core/hle/result.h" +#include "core/memory.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace LDR_RO @@ -21,14 +21,17 @@ namespace LDR_RO { // GCC versions < 5.0 do not implement std::is_trivially_copyable. // Excluding MSVC because it has weird behaviour for std::is_trivially_copyable. #if (__GNUC__ >= 5) || defined(__clang__) - #define ASSERT_CRO_STRUCT(name, size) \ - static_assert(std::is_standard_layout<name>::value, "CRO structure " #name " doesn't use standard layout"); \ - static_assert(std::is_trivially_copyable<name>::value, "CRO structure " #name " isn't trivially copyable"); \ - static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) +#define ASSERT_CRO_STRUCT(name, size) \ + static_assert(std::is_standard_layout<name>::value, \ + "CRO structure " #name " doesn't use standard layout"); \ + static_assert(std::is_trivially_copyable<name>::value, \ + "CRO structure " #name " isn't trivially copyable"); \ + static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) #else - #define ASSERT_CRO_STRUCT(name, size) \ - static_assert(std::is_standard_layout<name>::value, "CRO structure " #name " doesn't use standard layout"); \ - static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) +#define ASSERT_CRO_STRUCT(name, size) \ + static_assert(std::is_standard_layout<name>::value, \ + "CRO structure " #name " doesn't use standard layout"); \ + static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) #endif static constexpr u32 CRO_HEADER_SIZE = 0x138; @@ -59,9 +62,9 @@ public: * @param is_crs true if the module itself is the static module * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ - ResultCode Rebase(VAddr crs_address, u32 cro_size, - VAddr data_segment_addresss, u32 data_segment_size, - VAddr bss_segment_address, u32 bss_segment_size, bool is_crs); + ResultCode Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment_addresss, + u32 data_segment_size, VAddr bss_segment_address, u32 bss_segment_size, + bool is_crs); /** * Unrebases the module. @@ -148,8 +151,10 @@ private: const VAddr module_address; ///< the virtual address of this module /** - * Each item in this enum represents a u32 field in the header begin from address+0x80, successively. - * We don't directly use a struct here, to avoid GetPointer, reinterpret_cast, or Read/WriteBlock repeatedly. + * Each item in this enum represents a u32 field in the header begin from address+0x80, + * successively. + * We don't directly use a struct here, to avoid GetPointer, reinterpret_cast, or + * Read/WriteBlock repeatedly. */ enum HeaderField { Magic = 0, @@ -208,18 +213,20 @@ private: Fix2Barrier = ImportModuleTableOffset, Fix1Barrier = StaticAnonymousSymbolTableOffset, }; - static_assert(Fix0Barrier == (CRO_HEADER_SIZE - CRO_HASH_SIZE) / 4, "CRO Header fields are wrong!"); + static_assert(Fix0Barrier == (CRO_HEADER_SIZE - CRO_HASH_SIZE) / 4, + "CRO Header fields are wrong!"); enum class SegmentType : u32 { - Code = 0, + Code = 0, ROData = 1, - Data = 2, - BSS = 3, + Data = 2, + BSS = 3, }; /** * Identifies a program location inside of a segment. - * Required to refer to program locations because individual segments may be relocated independently of each other. + * Required to refer to program locations because individual segments may be relocated + * independently of each other. */ union SegmentTag { u32_le raw; @@ -227,7 +234,8 @@ private: BitField<4, 28, u32_le> offset_into_segment; SegmentTag() = default; - explicit SegmentTag(u32 raw_) : raw(raw_) {} + explicit SegmentTag(u32 raw_) : raw(raw_) { + } }; /// Information of a segment in this module. @@ -282,7 +290,7 @@ private: /// Identifies an indexed symbol imported from another module. struct ImportIndexedSymbolEntry { - u32_le index; // index of an ExportIndexedSymbolEntry in the exporting module + u32_le index; // index of an ExportIndexedSymbolEntry in the exporting module u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable static constexpr HeaderField TABLE_OFFSET_FIELD = ImportIndexedSymbolTableOffset; @@ -291,8 +299,8 @@ private: /// Identifies an anonymous symbol imported from another module. struct ImportAnonymousSymbolEntry { - SegmentTag symbol_position; // in the exporting segment - u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable + SegmentTag symbol_position; // in the exporting segment + u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable static constexpr HeaderField TABLE_OFFSET_FIELD = ImportAnonymousSymbolTableOffset; }; @@ -300,42 +308,47 @@ private: /// Information of a imported module and symbols imported from it. struct ImportModuleEntry { - u32_le name_offset; // pointing to a substring in ImportStrings - u32_le import_indexed_symbol_table_offset; // pointing to a subtable in ImportIndexedSymbolTable + u32_le name_offset; // pointing to a substring in ImportStrings + u32_le import_indexed_symbol_table_offset; // pointing to a subtable in + // ImportIndexedSymbolTable u32_le import_indexed_symbol_num; - u32_le import_anonymous_symbol_table_offset; // pointing to a subtable in ImportAnonymousSymbolTable + u32_le import_anonymous_symbol_table_offset; // pointing to a subtable in + // ImportAnonymousSymbolTable u32_le import_anonymous_symbol_num; static constexpr HeaderField TABLE_OFFSET_FIELD = ImportModuleTableOffset; void GetImportIndexedSymbolEntry(u32 index, ImportIndexedSymbolEntry& entry) { - Memory::ReadBlock(import_indexed_symbol_table_offset + index * sizeof(ImportIndexedSymbolEntry), - &entry, sizeof(ImportIndexedSymbolEntry)); + Memory::ReadBlock(import_indexed_symbol_table_offset + + index * sizeof(ImportIndexedSymbolEntry), + &entry, sizeof(ImportIndexedSymbolEntry)); } void GetImportAnonymousSymbolEntry(u32 index, ImportAnonymousSymbolEntry& entry) { - Memory::ReadBlock(import_anonymous_symbol_table_offset + index * sizeof(ImportAnonymousSymbolEntry), - &entry, sizeof(ImportAnonymousSymbolEntry)); + Memory::ReadBlock(import_anonymous_symbol_table_offset + + index * sizeof(ImportAnonymousSymbolEntry), + &entry, sizeof(ImportAnonymousSymbolEntry)); } }; ASSERT_CRO_STRUCT(ImportModuleEntry, 20); enum class RelocationType : u8 { - Nothing = 0, - AbsoluteAddress = 2, - RelativeAddress = 3, - ThumbBranch = 10, - ArmBranch = 28, - ModifyArmBranch = 29, - AbsoluteAddress2 = 38, + Nothing = 0, + AbsoluteAddress = 2, + RelativeAddress = 3, + ThumbBranch = 10, + ArmBranch = 28, + ModifyArmBranch = 29, + AbsoluteAddress2 = 38, AlignedRelativeAddress = 42, }; struct RelocationEntry { - SegmentTag target_position; // to self's segment as an ExternalRelocationEntry; to static module segment as a StaticRelocationEntry + SegmentTag target_position; // to self's segment as an ExternalRelocationEntry; to static + // module segment as a StaticRelocationEntry RelocationType type; u8 is_batch_end; - u8 is_batch_resolved; // set at a batch beginning if the batch is resolved + u8 is_batch_resolved; // set at a batch beginning if the batch is resolved INSERT_PADDING_BYTES(1); u32_le addend; }; @@ -366,8 +379,8 @@ private: /// Identifies a special static anonymous symbol (no game is known using this). struct StaticAnonymousSymbolEntry { - SegmentTag symbol_position; // to self's segment - u32_le relocation_batch_offset; // pointing to a relocation batch in StaticRelocationTable + SegmentTag symbol_position; // to self's segment + u32_le relocation_batch_offset; // pointing to a relocation batch in StaticRelocationTable static constexpr HeaderField TABLE_OFFSET_FIELD = StaticAnonymousSymbolTableOffset; }; @@ -446,12 +459,15 @@ private: } /** - * A helper function iterating over all registered auto-link modules, including the static module. + * A helper function iterating over all registered auto-link modules, including the static + * module. * @param crs_address the virtual address of the static module * @param func a function object to operate on a module. It accepts one parameter - * CROHelper and returns ResultVal<bool>. It should return true to continue the iteration, + * CROHelper and returns ResultVal<bool>. It should return true to continue the + * iteration, * false to stop the iteration, or an error code (which will also stop the iteration). - * @returns ResultCode indicating the result of the operation, RESULT_SUCCESS if all iteration success, + * @returns ResultCode indicating the result of the operation, RESULT_SUCCESS if all iteration + * success, * otherwise error code of the last iteration. */ template <typename FunctionObject> @@ -477,8 +493,8 @@ private: * Usually equals to target_address, but will be different for a target in .data segment * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ - ResultCode ApplyRelocation(VAddr target_address, RelocationType relocation_type, - u32 addend, u32 symbol_address, u32 target_future_address); + ResultCode ApplyRelocation(VAddr target_address, RelocationType relocation_type, u32 addend, + u32 symbol_address, u32 target_future_address); /** * Clears a relocation to zero @@ -492,7 +508,8 @@ private: * Applies or resets a batch of relocations * @param batch the virtual address of the first relocation in the batch * @param symbol_address the symbol address to be relocated with - * @param reset false to set the batch to resolved state, true to reset the batch to unresolved state + * @param reset false to set the batch to resolved state, true to reset the batch to unresolved + * state * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ ResultCode ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool reset = false); @@ -507,7 +524,8 @@ private: /** * Rebases offsets in module header according to module address. * @param cro_size the size of the CRO file - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseHeader(u32 cro_size); @@ -520,43 +538,49 @@ private: * @param bss_segment_size the buffer size for .bss segment * @returns ResultVal<VAddr> with the virtual address of .data segment in CRO. */ - ResultVal<VAddr> RebaseSegmentTable(u32 cro_size, - VAddr data_segment_address, u32 data_segment_size, - VAddr bss_segment_address, u32 bss_segment_size); + ResultVal<VAddr> RebaseSegmentTable(u32 cro_size, VAddr data_segment_address, + u32 data_segment_size, VAddr bss_segment_address, + u32 bss_segment_size); /** * Rebases offsets in exported named symbol table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseExportNamedSymbolTable(); /** * Verifies indices in export tree table. - * @returns ResultCode RESULT_SUCCESS if all indices are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all indices are verified as valid, otherwise error + * code. */ ResultCode VerifyExportTreeTable() const; /** * Rebases offsets in exported module table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseImportModuleTable(); /** * Rebases offsets in imported named symbol table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseImportNamedSymbolTable(); /** * Rebases offsets in imported indexed symbol table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseImportIndexedSymbolTable(); /** * Rebases offsets in imported anonymous symbol table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseImportAnonymousSymbolTable(); @@ -621,7 +645,8 @@ private: void UnrebaseHeader(); /** - * Looks up all imported named symbols of this module in all registered auto-link modules, and resolves them if found. + * Looks up all imported named symbols of this module in all registered auto-link modules, and + * resolves them if found. * @param crs_address the virtual address of the static module * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ @@ -646,7 +671,8 @@ private: ResultCode ResetImportAnonymousSymbol(); /** - * Finds registered auto-link modules that this module imports, and resolves indexed and anonymous symbols exported by them. + * Finds registered auto-link modules that this module imports, and resolves indexed and + * anonymous symbols exported by them. * @param crs_address the virtual address of the static module * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ @@ -667,7 +693,8 @@ private: ResultCode ResetExportNamedSymbol(CROHelper target); /** - * Resolves imported indexed and anonymous symbols in the target module which imports this module. + * Resolves imported indexed and anonymous symbols in the target module which imports this + * module. * @param target the module to resolve. * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp index 8ba73ea8d..ae5d3921f 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp @@ -18,24 +18,33 @@ namespace LDR_RO { -static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 - ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Permanent); -static const ResultCode ERROR_NOT_INITIALIZED = // 0xD9612FF8 - ResultCode(ErrorDescription::NotInitialized, ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Permanent); -static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F - ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, ErrorLevel::Usage); -static const ResultCode ERROR_MISALIGNED_ADDRESS = // 0xD9012FF1 - ResultCode(ErrorDescription::MisalignedAddress, ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); -static const ResultCode ERROR_MISALIGNED_SIZE = // 0xD9012FF2 - ResultCode(ErrorDescription::MisalignedSize, ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); -static const ResultCode ERROR_ILLEGAL_ADDRESS = // 0xE1612C0F - ResultCode(static_cast<ErrorDescription>(15), ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Usage); -static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08 - ResultCode(static_cast<ErrorDescription>(8), ErrorModule::RO, ErrorSummary::InvalidState, ErrorLevel::Permanent); -static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D - ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState, ErrorLevel::Permanent); -static const ResultCode ERROR_INVALID_DESCRIPTOR = // 0xD9001830 - ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent); +static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 + ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal, + ErrorLevel::Permanent); +static const ResultCode ERROR_NOT_INITIALIZED = // 0xD9612FF8 + ResultCode(ErrorDescription::NotInitialized, ErrorModule::RO, ErrorSummary::Internal, + ErrorLevel::Permanent); +static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F + ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, + ErrorLevel::Usage); +static const ResultCode ERROR_MISALIGNED_ADDRESS = // 0xD9012FF1 + ResultCode(ErrorDescription::MisalignedAddress, ErrorModule::RO, ErrorSummary::WrongArgument, + ErrorLevel::Permanent); +static const ResultCode ERROR_MISALIGNED_SIZE = // 0xD9012FF2 + ResultCode(ErrorDescription::MisalignedSize, ErrorModule::RO, ErrorSummary::WrongArgument, + ErrorLevel::Permanent); +static const ResultCode ERROR_ILLEGAL_ADDRESS = // 0xE1612C0F + ResultCode(static_cast<ErrorDescription>(15), ErrorModule::RO, ErrorSummary::Internal, + ErrorLevel::Usage); +static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08 + ResultCode(static_cast<ErrorDescription>(8), ErrorModule::RO, ErrorSummary::InvalidState, + ErrorLevel::Permanent); +static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D + ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState, + ErrorLevel::Permanent); +static const ResultCode ERROR_INVALID_DESCRIPTOR = // 0xD9001830 + ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); static MemorySynchronizer memory_synchronizer; @@ -44,10 +53,10 @@ static VAddr loaded_crs; ///< the virtual address of the static module static bool VerifyBufferState(VAddr buffer_ptr, u32 size) { auto vma = Kernel::g_current_process->vm_manager.FindVMA(buffer_ptr); - return vma != Kernel::g_current_process->vm_manager.vma_map.end() - && vma->second.base + vma->second.size >= buffer_ptr + size - && vma->second.permissions == Kernel::VMAPermission::ReadWrite - && vma->second.meminfo_state == Kernel::MemoryState::Private; + return vma != Kernel::g_current_process->vm_manager.vma_map.end() && + vma->second.base + vma->second.size >= buffer_ptr + size && + vma->second.permissions == Kernel::VMAPermission::ReadWrite && + vma->second.meminfo_state == Kernel::MemoryState::Private; } /** @@ -66,13 +75,14 @@ static bool VerifyBufferState(VAddr buffer_ptr, u32 size) { static void Initialize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr crs_buffer_ptr = cmd_buff[1]; - u32 crs_size = cmd_buff[2]; - VAddr crs_address = cmd_buff[3]; - u32 descriptor = cmd_buff[4]; - u32 process = cmd_buff[5]; + u32 crs_size = cmd_buff[2]; + VAddr crs_address = cmd_buff[3]; + u32 descriptor = cmd_buff[4]; + u32 process = cmd_buff[5]; - LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, crs_address=0x%08X, crs_size=0x%X, descriptor=0x%08X, process=0x%08X", - crs_buffer_ptr, crs_address, crs_size, descriptor, process); + LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, crs_address=0x%08X, crs_size=0x%X, " + "descriptor=0x%08X, process=0x%08X", + crs_buffer_ptr, crs_address, crs_size, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -119,7 +129,8 @@ static void Initialize(Service::Interface* self) { return; } - if (crs_address < Memory::PROCESS_IMAGE_VADDR || crs_address + crs_size > Memory::PROCESS_IMAGE_VADDR_END) { + if (crs_address < Memory::PROCESS_IMAGE_VADDR || + crs_address + crs_size > Memory::PROCESS_IMAGE_VADDR_END) { LOG_ERROR(Service_LDR, "CRS mapping address is not in the process image region"); cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw; return; @@ -131,14 +142,17 @@ static void Initialize(Service::Interface* self) { // TODO(wwylele): should be memory aliasing std::shared_ptr<std::vector<u8>> crs_mem = std::make_shared<std::vector<u8>>(crs_size); Memory::ReadBlock(crs_buffer_ptr, crs_mem->data(), crs_size); - result = Kernel::g_current_process->vm_manager.MapMemoryBlock(crs_address, crs_mem, 0, crs_size, Kernel::MemoryState::Code).Code(); + result = Kernel::g_current_process->vm_manager + .MapMemoryBlock(crs_address, crs_mem, 0, crs_size, Kernel::MemoryState::Code) + .Code(); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw); cmd_buff[1] = result.raw; return; } - result = Kernel::g_current_process->vm_manager.ReprotectRange(crs_address, crs_size, Kernel::VMAPermission::Read); + result = Kernel::g_current_process->vm_manager.ReprotectRange(crs_address, crs_size, + Kernel::VMAPermission::Read); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); cmd_buff[1] = result.raw; @@ -186,9 +200,9 @@ static void Initialize(Service::Interface* self) { static void LoadCRR(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 crr_buffer_ptr = cmd_buff[1]; - u32 crr_size = cmd_buff[2]; - u32 descriptor = cmd_buff[3]; - u32 process = cmd_buff[4]; + u32 crr_size = cmd_buff[2]; + u32 descriptor = cmd_buff[3]; + u32 process = cmd_buff[4]; if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -200,7 +214,8 @@ static void LoadCRR(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(2, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, crr_size=0x%08X, descriptor=0x%08X, process=0x%08X", + LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, crr_size=0x%08X, " + "descriptor=0x%08X, process=0x%08X", crr_buffer_ptr, crr_size, descriptor, process); } @@ -218,8 +233,8 @@ static void LoadCRR(Service::Interface* self) { static void UnloadCRR(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 crr_buffer_ptr = cmd_buff[1]; - u32 descriptor = cmd_buff[2]; - u32 process = cmd_buff[3]; + u32 descriptor = cmd_buff[2]; + u32 process = cmd_buff[3]; if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -231,7 +246,8 @@ static void UnloadCRR(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(3, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", + LOG_WARNING(Service_LDR, + "(STUBBED) called, crr_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", crr_buffer_ptr, descriptor, process); } @@ -263,27 +279,28 @@ static void UnloadCRR(Service::Interface* self) { */ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { u32* cmd_buff = Kernel::GetCommandBuffer(); - VAddr cro_buffer_ptr = cmd_buff[1]; - VAddr cro_address = cmd_buff[2]; - u32 cro_size = cmd_buff[3]; + VAddr cro_buffer_ptr = cmd_buff[1]; + VAddr cro_address = cmd_buff[2]; + u32 cro_size = cmd_buff[3]; VAddr data_segment_address = cmd_buff[4]; - u32 zero = cmd_buff[5]; - u32 data_segment_size = cmd_buff[6]; - u32 bss_segment_address = cmd_buff[7]; - u32 bss_segment_size = cmd_buff[8]; - bool auto_link = (cmd_buff[9] & 0xFF) != 0; - u32 fix_level = cmd_buff[10]; - VAddr crr_address = cmd_buff[11]; - u32 descriptor = cmd_buff[12]; - u32 process = cmd_buff[13]; - - LOG_DEBUG(Service_LDR, "called (%s), cro_buffer_ptr=0x%08X, cro_address=0x%08X, cro_size=0x%X, " - "data_segment_address=0x%08X, zero=%d, data_segment_size=0x%X, bss_segment_address=0x%08X, bss_segment_size=0x%X, " - "auto_link=%s, fix_level=%d, crr_address=0x%08X, descriptor=0x%08X, process=0x%08X", - link_on_load_bug_fix ? "new" : "old", cro_buffer_ptr, cro_address, cro_size, - data_segment_address, zero, data_segment_size, bss_segment_address, bss_segment_size, - auto_link ? "true" : "false", fix_level, crr_address, descriptor, process - ); + u32 zero = cmd_buff[5]; + u32 data_segment_size = cmd_buff[6]; + u32 bss_segment_address = cmd_buff[7]; + u32 bss_segment_size = cmd_buff[8]; + bool auto_link = (cmd_buff[9] & 0xFF) != 0; + u32 fix_level = cmd_buff[10]; + VAddr crr_address = cmd_buff[11]; + u32 descriptor = cmd_buff[12]; + u32 process = cmd_buff[13]; + + LOG_DEBUG(Service_LDR, + "called (%s), cro_buffer_ptr=0x%08X, cro_address=0x%08X, cro_size=0x%X, " + "data_segment_address=0x%08X, zero=%d, data_segment_size=0x%X, " + "bss_segment_address=0x%08X, bss_segment_size=0x%X, " + "auto_link=%s, fix_level=%d, crr_address=0x%08X, descriptor=0x%08X, process=0x%08X", + link_on_load_bug_fix ? "new" : "old", cro_buffer_ptr, cro_address, cro_size, + data_segment_address, zero, data_segment_size, bss_segment_address, bss_segment_size, + auto_link ? "true" : "false", fix_level, crr_address, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -330,8 +347,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { return; } - if (cro_address < Memory::PROCESS_IMAGE_VADDR - || cro_address + cro_size > Memory::PROCESS_IMAGE_VADDR_END) { + if (cro_address < Memory::PROCESS_IMAGE_VADDR || + cro_address + cro_size > Memory::PROCESS_IMAGE_VADDR_END) { LOG_ERROR(Service_LDR, "CRO mapping address is not in the process image region"); cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw; return; @@ -339,7 +356,9 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { if (zero) { LOG_ERROR(Service_LDR, "Zero is not zero %d", zero); - cmd_buff[1] = ResultCode(static_cast<ErrorDescription>(29), ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Usage).raw; + cmd_buff[1] = ResultCode(static_cast<ErrorDescription>(29), ErrorModule::RO, + ErrorSummary::Internal, ErrorLevel::Usage) + .raw; return; } @@ -349,14 +368,17 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { // TODO(wwylele): should be memory aliasing std::shared_ptr<std::vector<u8>> cro_mem = std::make_shared<std::vector<u8>>(cro_size); Memory::ReadBlock(cro_buffer_ptr, cro_mem->data(), cro_size); - result = Kernel::g_current_process->vm_manager.MapMemoryBlock(cro_address, cro_mem, 0, cro_size, Kernel::MemoryState::Code).Code(); + result = Kernel::g_current_process->vm_manager + .MapMemoryBlock(cro_address, cro_mem, 0, cro_size, Kernel::MemoryState::Code) + .Code(); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw); cmd_buff[1] = result.raw; return; } - result = Kernel::g_current_process->vm_manager.ReprotectRange(cro_address, cro_size, Kernel::VMAPermission::Read); + result = Kernel::g_current_process->vm_manager.ReprotectRange(cro_address, cro_size, + Kernel::VMAPermission::Read); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); @@ -384,7 +406,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { return; } - result = cro.Rebase(loaded_crs, cro_size, data_segment_address, data_segment_size, bss_segment_address, bss_segment_size, false); + result = cro.Rebase(loaded_crs, cro_size, data_segment_address, data_segment_size, + bss_segment_address, bss_segment_size, false); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error rebasing CRO %08X", result.raw); Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); @@ -409,7 +432,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { // TODO(wwylele): verify the behaviour when buffer_ptr == address if (cro_buffer_ptr != cro_address) { if (fix_size != cro_size) { - result = Kernel::g_current_process->vm_manager.UnmapRange(cro_address + fix_size, cro_size - fix_size); + result = Kernel::g_current_process->vm_manager.UnmapRange(cro_address + fix_size, + cro_size - fix_size); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error unmapping memory block %08X", result.raw); Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); @@ -426,7 +450,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { u32 exe_size; std::tie(exe_begin, exe_size) = cro.GetExecutablePages(); if (exe_begin) { - result = Kernel::g_current_process->vm_manager.ReprotectRange(exe_begin, exe_size, Kernel::VMAPermission::ReadExecute); + result = Kernel::g_current_process->vm_manager.ReprotectRange( + exe_begin, exe_size, Kernel::VMAPermission::ReadExecute); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); Kernel::g_current_process->vm_manager.UnmapRange(cro_address, fix_size); @@ -437,8 +462,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { Core::g_app_core->ClearInstructionCache(); - LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", - cro.ModuleName().data(), cro_address, cro_address+fix_size); + LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(), + cro_address, cro_address + fix_size); cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = fix_size; @@ -464,14 +489,15 @@ static void LoadCRO(Service::Interface* self) { */ static void UnloadCRO(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - VAddr cro_address = cmd_buff[1]; - u32 zero = cmd_buff[2]; - VAddr cro_buffer_ptr = cmd_buff[3]; - u32 descriptor = cmd_buff[4]; - u32 process = cmd_buff[5]; + VAddr cro_address = cmd_buff[1]; + u32 zero = cmd_buff[2]; + VAddr cro_buffer_ptr = cmd_buff[3]; + u32 descriptor = cmd_buff[4]; + u32 process = cmd_buff[5]; - LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, zero=%d, cro_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", - cro_address, zero, cro_buffer_ptr, descriptor, process); + LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, zero=%d, cro_buffer_ptr=0x%08X, " + "descriptor=0x%08X, process=0x%08X", + cro_address, zero, cro_buffer_ptr, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -558,11 +584,11 @@ static void UnloadCRO(Service::Interface* self) { static void LinkCRO(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr cro_address = cmd_buff[1]; - u32 descriptor = cmd_buff[2]; - u32 process = cmd_buff[3]; + u32 descriptor = cmd_buff[2]; + u32 process = cmd_buff[3]; LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X", - cro_address, descriptor, process); + cro_address, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -620,11 +646,11 @@ static void LinkCRO(Service::Interface* self) { static void UnlinkCRO(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr cro_address = cmd_buff[1]; - u32 descriptor = cmd_buff[2]; - u32 process = cmd_buff[3]; + u32 descriptor = cmd_buff[2]; + u32 process = cmd_buff[3]; LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X", - cro_address, descriptor, process); + cro_address, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -682,11 +708,11 @@ static void UnlinkCRO(Service::Interface* self) { static void Shutdown(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr crs_buffer_ptr = cmd_buff[1]; - u32 descriptor = cmd_buff[2]; - u32 process = cmd_buff[3]; + u32 descriptor = cmd_buff[2]; + u32 process = cmd_buff[3]; LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", - crs_buffer_ptr, descriptor, process); + crs_buffer_ptr, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -724,15 +750,11 @@ static void Shutdown(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x000100C2, Initialize, "Initialize"}, - {0x00020082, LoadCRR, "LoadCRR"}, - {0x00030042, UnloadCRR, "UnloadCRR"}, - {0x000402C2, LoadCRO<false>, "LoadCRO"}, - {0x000500C2, UnloadCRO, "UnloadCRO"}, - {0x00060042, LinkCRO, "LinkCRO"}, - {0x00070042, UnlinkCRO, "UnlinkCRO"}, - {0x00080042, Shutdown, "Shutdown"}, - {0x000902C2, LoadCRO<true>, "LoadCRO_New"}, + {0x000100C2, Initialize, "Initialize"}, {0x00020082, LoadCRR, "LoadCRR"}, + {0x00030042, UnloadCRR, "UnloadCRR"}, {0x000402C2, LoadCRO<false>, "LoadCRO"}, + {0x000500C2, UnloadCRO, "UnloadCRO"}, {0x00060042, LinkCRO, "LinkCRO"}, + {0x00070042, UnlinkCRO, "UnlinkCRO"}, {0x00080042, Shutdown, "Shutdown"}, + {0x000902C2, LoadCRO<true>, "LoadCRO_New"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ldr_ro/memory_synchronizer.cpp b/src/core/hle/service/ldr_ro/memory_synchronizer.cpp index 4402876e6..aed6d3365 100644 --- a/src/core/hle/service/ldr_ro/memory_synchronizer.cpp +++ b/src/core/hle/service/ldr_ro/memory_synchronizer.cpp @@ -14,9 +14,8 @@ namespace LDR_RO { auto MemorySynchronizer::FindMemoryBlock(VAddr mapping, VAddr original) { - auto block = std::find_if(memory_blocks.begin(), memory_blocks.end(), [=](MemoryBlock& b){ - return b.original == original; - }); + auto block = std::find_if(memory_blocks.begin(), memory_blocks.end(), + [=](MemoryBlock& b) { return b.original == original; }); ASSERT(block->mapping == mapping); return block; } |