|
|
|
@@ -55,7 +55,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const {
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
SegmentEntry entry;
|
|
|
|
|
GetEntry(segment_tag.segment_index, entry);
|
|
|
|
|
GetEntry(memory, segment_tag.segment_index, entry);
|
|
|
|
|
|
|
|
|
|
if (segment_tag.offset_into_segment >= entry.size)
|
|
|
|
|
return 0;
|
|
|
|
@@ -121,7 +121,7 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
|
|
|
|
|
VAddr relocation_address = batch;
|
|
|
|
|
while (true) {
|
|
|
|
|
RelocationEntry relocation;
|
|
|
|
|
Memory::ReadBlock(process, relocation_address, &relocation, sizeof(RelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, relocation_address, &relocation, sizeof(RelocationEntry));
|
|
|
|
|
|
|
|
|
|
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
|
|
|
|
if (relocation_target == 0) {
|
|
|
|
@@ -142,9 +142,9 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RelocationEntry relocation;
|
|
|
|
|
Memory::ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
|
|
|
|
relocation.is_batch_resolved = reset ? 0 : 1;
|
|
|
|
|
Memory::WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
|
|
|
|
memory.WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -154,13 +154,13 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
|
|
|
|
|
|
|
|
|
|
std::size_t len = name.size();
|
|
|
|
|
ExportTreeEntry entry;
|
|
|
|
|
GetEntry(0, entry);
|
|
|
|
|
GetEntry(memory, 0, entry);
|
|
|
|
|
ExportTreeEntry::Child next;
|
|
|
|
|
next.raw = entry.left.raw;
|
|
|
|
|
u32 found_id;
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
GetEntry(next.next_index, entry);
|
|
|
|
|
GetEntry(memory, next.next_index, entry);
|
|
|
|
|
|
|
|
|
|
if (next.is_end) {
|
|
|
|
|
found_id = entry.export_table_index;
|
|
|
|
@@ -186,7 +186,7 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
|
|
|
|
|
|
|
|
|
|
u32 export_strings_size = GetField(ExportStringsSize);
|
|
|
|
|
ExportNamedSymbolEntry symbol_entry;
|
|
|
|
|
GetEntry(found_id, symbol_entry);
|
|
|
|
|
GetEntry(memory, found_id, symbol_entry);
|
|
|
|
|
|
|
|
|
|
if (memory.ReadCString(symbol_entry.name_offset, export_strings_size) != name)
|
|
|
|
|
return 0;
|
|
|
|
@@ -279,7 +279,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
|
|
|
|
|
u32 segment_num = GetField(SegmentNum);
|
|
|
|
|
for (u32 i = 0; i < segment_num; ++i) {
|
|
|
|
|
SegmentEntry segment;
|
|
|
|
|
GetEntry(i, segment);
|
|
|
|
|
GetEntry(memory, i, segment);
|
|
|
|
|
if (segment.type == SegmentType::Data) {
|
|
|
|
|
if (segment.size != 0) {
|
|
|
|
|
if (segment.size > data_segment_size)
|
|
|
|
@@ -298,7 +298,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
|
|
|
|
|
if (segment.offset > module_address + cro_size)
|
|
|
|
|
return CROFormatError(0x19);
|
|
|
|
|
}
|
|
|
|
|
SetEntry(i, segment);
|
|
|
|
|
SetEntry(memory, i, segment);
|
|
|
|
|
}
|
|
|
|
|
return MakeResult<u32>(prev_data_segment + module_address);
|
|
|
|
|
}
|
|
|
|
@@ -310,7 +310,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
|
|
|
|
|
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < export_named_symbol_num; ++i) {
|
|
|
|
|
ExportNamedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.name_offset != 0) {
|
|
|
|
|
entry.name_offset += module_address;
|
|
|
|
@@ -320,7 +320,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@@ -329,7 +329,7 @@ ResultCode CROHelper::VerifyExportTreeTable() const {
|
|
|
|
|
u32 tree_num = GetField(ExportTreeNum);
|
|
|
|
|
for (u32 i = 0; i < tree_num; ++i) {
|
|
|
|
|
ExportTreeEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.left.next_index >= tree_num || entry.right.next_index >= tree_num) {
|
|
|
|
|
return CROFormatError(0x11);
|
|
|
|
@@ -353,7 +353,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
|
|
|
|
|
u32 module_num = GetField(ImportModuleNum);
|
|
|
|
|
for (u32 i = 0; i < module_num; ++i) {
|
|
|
|
|
ImportModuleEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.name_offset != 0) {
|
|
|
|
|
entry.name_offset += module_address;
|
|
|
|
@@ -379,7 +379,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@@ -395,7 +395,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
|
|
|
|
|
u32 num = GetField(ImportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < num; ++i) {
|
|
|
|
|
ImportNamedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.name_offset != 0) {
|
|
|
|
|
entry.name_offset += module_address;
|
|
|
|
@@ -413,7 +413,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@@ -427,7 +427,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
|
|
|
|
|
u32 num = GetField(ImportIndexedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < num; ++i) {
|
|
|
|
|
ImportIndexedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.relocation_batch_offset != 0) {
|
|
|
|
|
entry.relocation_batch_offset += module_address;
|
|
|
|
@@ -437,7 +437,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@@ -451,7 +451,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
|
|
|
|
|
u32 num = GetField(ImportAnonymousSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < num; ++i) {
|
|
|
|
|
ImportAnonymousSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.relocation_batch_offset != 0) {
|
|
|
|
|
entry.relocation_batch_offset += module_address;
|
|
|
|
@@ -461,7 +461,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@@ -476,14 +476,14 @@ ResultCode CROHelper::ResetExternalRelocations() {
|
|
|
|
|
ExternalRelocationEntry relocation;
|
|
|
|
|
|
|
|
|
|
// Verifies that the last relocation is the end of a batch
|
|
|
|
|
GetEntry(external_relocation_num - 1, relocation);
|
|
|
|
|
GetEntry(memory, external_relocation_num - 1, relocation);
|
|
|
|
|
if (!relocation.is_batch_end) {
|
|
|
|
|
return CROFormatError(0x12);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool batch_begin = true;
|
|
|
|
|
for (u32 i = 0; i < external_relocation_num; ++i) {
|
|
|
|
|
GetEntry(i, relocation);
|
|
|
|
|
GetEntry(memory, i, relocation);
|
|
|
|
|
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
|
|
|
|
|
|
|
|
|
if (relocation_target == 0) {
|
|
|
|
@@ -500,7 +500,7 @@ ResultCode CROHelper::ResetExternalRelocations() {
|
|
|
|
|
if (batch_begin) {
|
|
|
|
|
// resets to unresolved state
|
|
|
|
|
relocation.is_batch_resolved = 0;
|
|
|
|
|
SetEntry(i, relocation);
|
|
|
|
|
SetEntry(memory, i, relocation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if current is an end, then the next is a beginning
|
|
|
|
@@ -516,7 +516,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
|
|
|
|
|
|
|
|
|
|
bool batch_begin = true;
|
|
|
|
|
for (u32 i = 0; i < external_relocation_num; ++i) {
|
|
|
|
|
GetEntry(i, relocation);
|
|
|
|
|
GetEntry(memory, i, relocation);
|
|
|
|
|
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
|
|
|
|
|
|
|
|
|
if (relocation_target == 0) {
|
|
|
|
@@ -532,7 +532,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
|
|
|
|
|
if (batch_begin) {
|
|
|
|
|
// resets to unresolved state
|
|
|
|
|
relocation.is_batch_resolved = 0;
|
|
|
|
|
SetEntry(i, relocation);
|
|
|
|
|
SetEntry(memory, i, relocation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if current is an end, then the next is a beginning
|
|
|
|
@@ -554,7 +554,7 @@ ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) {
|
|
|
|
|
offset_export_num);
|
|
|
|
|
for (u32 i = 0; i < offset_export_num; ++i) {
|
|
|
|
|
StaticAnonymousSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
u32 batch_address = entry.relocation_batch_offset + module_address;
|
|
|
|
|
|
|
|
|
|
if (batch_address < static_relocation_table_offset ||
|
|
|
|
@@ -579,7 +579,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|
|
|
|
u32 internal_relocation_num = GetField(InternalRelocationNum);
|
|
|
|
|
for (u32 i = 0; i < internal_relocation_num; ++i) {
|
|
|
|
|
InternalRelocationEntry relocation;
|
|
|
|
|
GetEntry(i, relocation);
|
|
|
|
|
GetEntry(memory, i, relocation);
|
|
|
|
|
VAddr target_addressB = SegmentTagToAddress(relocation.target_position);
|
|
|
|
|
if (target_addressB == 0) {
|
|
|
|
|
return CROFormatError(0x15);
|
|
|
|
@@ -587,7 +587,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|
|
|
|
|
|
|
|
|
VAddr target_address;
|
|
|
|
|
SegmentEntry target_segment;
|
|
|
|
|
GetEntry(relocation.target_position.segment_index, target_segment);
|
|
|
|
|
GetEntry(memory, relocation.target_position.segment_index, target_segment);
|
|
|
|
|
|
|
|
|
|
if (target_segment.type == SegmentType::Data) {
|
|
|
|
|
// If the relocation is to the .data segment, we need to relocate it in the old buffer
|
|
|
|
@@ -602,7 +602,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SegmentEntry symbol_segment;
|
|
|
|
|
GetEntry(relocation.symbol_segment, symbol_segment);
|
|
|
|
|
GetEntry(memory, relocation.symbol_segment, symbol_segment);
|
|
|
|
|
LOG_TRACE(Service_LDR, "Internally relocates 0x{:08X} with 0x{:08X}", target_address,
|
|
|
|
|
symbol_segment.offset);
|
|
|
|
|
ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend,
|
|
|
|
@@ -619,7 +619,7 @@ ResultCode CROHelper::ClearInternalRelocations() {
|
|
|
|
|
u32 internal_relocation_num = GetField(InternalRelocationNum);
|
|
|
|
|
for (u32 i = 0; i < internal_relocation_num; ++i) {
|
|
|
|
|
InternalRelocationEntry relocation;
|
|
|
|
|
GetEntry(i, relocation);
|
|
|
|
|
GetEntry(memory, i, relocation);
|
|
|
|
|
VAddr target_address = SegmentTagToAddress(relocation.target_position);
|
|
|
|
|
|
|
|
|
|
if (target_address == 0) {
|
|
|
|
@@ -639,13 +639,13 @@ void CROHelper::UnrebaseImportAnonymousSymbolTable() {
|
|
|
|
|
u32 num = GetField(ImportAnonymousSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < num; ++i) {
|
|
|
|
|
ImportAnonymousSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.relocation_batch_offset != 0) {
|
|
|
|
|
entry.relocation_batch_offset -= module_address;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -653,13 +653,13 @@ void CROHelper::UnrebaseImportIndexedSymbolTable() {
|
|
|
|
|
u32 num = GetField(ImportIndexedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < num; ++i) {
|
|
|
|
|
ImportIndexedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.relocation_batch_offset != 0) {
|
|
|
|
|
entry.relocation_batch_offset -= module_address;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -667,7 +667,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
|
|
|
|
|
u32 num = GetField(ImportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < num; ++i) {
|
|
|
|
|
ImportNamedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.name_offset != 0) {
|
|
|
|
|
entry.name_offset -= module_address;
|
|
|
|
@@ -677,7 +677,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
|
|
|
|
|
entry.relocation_batch_offset -= module_address;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -685,7 +685,7 @@ void CROHelper::UnrebaseImportModuleTable() {
|
|
|
|
|
u32 module_num = GetField(ImportModuleNum);
|
|
|
|
|
for (u32 i = 0; i < module_num; ++i) {
|
|
|
|
|
ImportModuleEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.name_offset != 0) {
|
|
|
|
|
entry.name_offset -= module_address;
|
|
|
|
@@ -699,7 +699,7 @@ void CROHelper::UnrebaseImportModuleTable() {
|
|
|
|
|
entry.import_anonymous_symbol_table_offset -= module_address;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -707,13 +707,13 @@ void CROHelper::UnrebaseExportNamedSymbolTable() {
|
|
|
|
|
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < export_named_symbol_num; ++i) {
|
|
|
|
|
ExportNamedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (entry.name_offset != 0) {
|
|
|
|
|
entry.name_offset -= module_address;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, entry);
|
|
|
|
|
SetEntry(memory, i, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -721,7 +721,7 @@ void CROHelper::UnrebaseSegmentTable() {
|
|
|
|
|
u32 segment_num = GetField(SegmentNum);
|
|
|
|
|
for (u32 i = 0; i < segment_num; ++i) {
|
|
|
|
|
SegmentEntry segment;
|
|
|
|
|
GetEntry(i, segment);
|
|
|
|
|
GetEntry(memory, i, segment);
|
|
|
|
|
|
|
|
|
|
if (segment.type == SegmentType::BSS) {
|
|
|
|
|
segment.offset = 0;
|
|
|
|
@@ -729,7 +729,7 @@ void CROHelper::UnrebaseSegmentTable() {
|
|
|
|
|
segment.offset -= module_address;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetEntry(i, segment);
|
|
|
|
|
SetEntry(memory, i, segment);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -751,11 +751,11 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) {
|
|
|
|
|
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < symbol_import_num; ++i) {
|
|
|
|
|
ImportNamedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
|
|
|
|
ExternalRelocationEntry relocation_entry;
|
|
|
|
|
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
|
|
|
|
|
if (!relocation_entry.is_batch_resolved) {
|
|
|
|
|
ResultCode result = ForEachAutoLinkCRO(
|
|
|
|
@@ -794,11 +794,11 @@ ResultCode CROHelper::ResetImportNamedSymbol() {
|
|
|
|
|
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < symbol_import_num; ++i) {
|
|
|
|
|
ImportNamedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
|
|
|
|
ExternalRelocationEntry relocation_entry;
|
|
|
|
|
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
|
|
|
|
|
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
|
|
|
|
if (result.IsError()) {
|
|
|
|
@@ -815,11 +815,11 @@ ResultCode CROHelper::ResetImportIndexedSymbol() {
|
|
|
|
|
u32 import_num = GetField(ImportIndexedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < import_num; ++i) {
|
|
|
|
|
ImportIndexedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
|
|
|
|
ExternalRelocationEntry relocation_entry;
|
|
|
|
|
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
|
|
|
|
|
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
|
|
|
|
if (result.IsError()) {
|
|
|
|
@@ -836,11 +836,11 @@ ResultCode CROHelper::ResetImportAnonymousSymbol() {
|
|
|
|
|
u32 import_num = GetField(ImportAnonymousSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < import_num; ++i) {
|
|
|
|
|
ImportAnonymousSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
|
|
|
|
ExternalRelocationEntry relocation_entry;
|
|
|
|
|
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
|
|
|
|
|
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
|
|
|
|
if (result.IsError()) {
|
|
|
|
@@ -857,7 +857,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
|
|
|
|
|
u32 import_module_num = GetField(ImportModuleNum);
|
|
|
|
|
for (u32 i = 0; i < import_module_num; ++i) {
|
|
|
|
|
ImportModuleEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
std::string want_cro_name = memory.ReadCString(entry.name_offset, import_strings_size);
|
|
|
|
|
|
|
|
|
|
ResultCode result = ForEachAutoLinkCRO(
|
|
|
|
@@ -867,9 +867,9 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
|
|
|
|
|
ModuleName(), entry.import_indexed_symbol_num, source.ModuleName());
|
|
|
|
|
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
|
|
|
|
ImportIndexedSymbolEntry im;
|
|
|
|
|
entry.GetImportIndexedSymbolEntry(process, j, im);
|
|
|
|
|
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
|
|
|
|
ExportIndexedSymbolEntry ex;
|
|
|
|
|
source.GetEntry(im.index, ex);
|
|
|
|
|
source.GetEntry(memory, im.index, ex);
|
|
|
|
|
u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position);
|
|
|
|
|
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
|
|
|
|
|
ResultCode result =
|
|
|
|
@@ -884,7 +884,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
|
|
|
|
|
ModuleName(), entry.import_anonymous_symbol_num, source.ModuleName());
|
|
|
|
|
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
|
|
|
|
ImportAnonymousSymbolEntry im;
|
|
|
|
|
entry.GetImportAnonymousSymbolEntry(process, j, im);
|
|
|
|
|
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
|
|
|
|
u32 symbol_address = source.SegmentTagToAddress(im.symbol_position);
|
|
|
|
|
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
|
|
|
|
|
ResultCode result =
|
|
|
|
@@ -913,11 +913,11 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) {
|
|
|
|
|
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < target_symbol_import_num; ++i) {
|
|
|
|
|
ImportNamedSymbolEntry entry;
|
|
|
|
|
target.GetEntry(i, entry);
|
|
|
|
|
target.GetEntry(memory, i, entry);
|
|
|
|
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
|
|
|
|
ExternalRelocationEntry relocation_entry;
|
|
|
|
|
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
|
|
|
|
|
if (!relocation_entry.is_batch_resolved) {
|
|
|
|
|
std::string symbol_name =
|
|
|
|
@@ -944,11 +944,11 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) {
|
|
|
|
|
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < target_symbol_import_num; ++i) {
|
|
|
|
|
ImportNamedSymbolEntry entry;
|
|
|
|
|
target.GetEntry(i, entry);
|
|
|
|
|
target.GetEntry(memory, i, entry);
|
|
|
|
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
|
|
|
|
ExternalRelocationEntry relocation_entry;
|
|
|
|
|
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
|
|
|
|
|
if (relocation_entry.is_batch_resolved) {
|
|
|
|
|
std::string symbol_name =
|
|
|
|
@@ -974,7 +974,7 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
|
|
|
|
|
u32 target_import_module_num = target.GetField(ImportModuleNum);
|
|
|
|
|
for (u32 i = 0; i < target_import_module_num; ++i) {
|
|
|
|
|
ImportModuleEntry entry;
|
|
|
|
|
target.GetEntry(i, entry);
|
|
|
|
|
target.GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name)
|
|
|
|
|
continue;
|
|
|
|
@@ -983,9 +983,9 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
|
|
|
|
|
entry.import_indexed_symbol_num, target.ModuleName());
|
|
|
|
|
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
|
|
|
|
ImportIndexedSymbolEntry im;
|
|
|
|
|
entry.GetImportIndexedSymbolEntry(process, j, im);
|
|
|
|
|
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
|
|
|
|
ExportIndexedSymbolEntry ex;
|
|
|
|
|
GetEntry(im.index, ex);
|
|
|
|
|
GetEntry(memory, im.index, ex);
|
|
|
|
|
u32 symbol_address = SegmentTagToAddress(ex.symbol_position);
|
|
|
|
|
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
|
|
|
|
|
ResultCode result =
|
|
|
|
@@ -1000,7 +1000,7 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
|
|
|
|
|
entry.import_anonymous_symbol_num, target.ModuleName());
|
|
|
|
|
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
|
|
|
|
ImportAnonymousSymbolEntry im;
|
|
|
|
|
entry.GetImportAnonymousSymbolEntry(process, j, im);
|
|
|
|
|
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
|
|
|
|
u32 symbol_address = SegmentTagToAddress(im.symbol_position);
|
|
|
|
|
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
|
|
|
|
|
ResultCode result =
|
|
|
|
@@ -1023,7 +1023,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
|
|
|
|
|
u32 target_import_module_num = target.GetField(ImportModuleNum);
|
|
|
|
|
for (u32 i = 0; i < target_import_module_num; ++i) {
|
|
|
|
|
ImportModuleEntry entry;
|
|
|
|
|
target.GetEntry(i, entry);
|
|
|
|
|
target.GetEntry(memory, i, entry);
|
|
|
|
|
|
|
|
|
|
if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name)
|
|
|
|
|
continue;
|
|
|
|
@@ -1032,7 +1032,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
|
|
|
|
|
target.ModuleName());
|
|
|
|
|
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
|
|
|
|
ImportIndexedSymbolEntry im;
|
|
|
|
|
entry.GetImportIndexedSymbolEntry(process, j, im);
|
|
|
|
|
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
|
|
|
|
ResultCode result =
|
|
|
|
|
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
|
|
|
|
|
if (result.IsError()) {
|
|
|
|
@@ -1045,7 +1045,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
|
|
|
|
|
target.ModuleName());
|
|
|
|
|
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
|
|
|
|
ImportAnonymousSymbolEntry im;
|
|
|
|
|
entry.GetImportAnonymousSymbolEntry(process, j, im);
|
|
|
|
|
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
|
|
|
|
ResultCode result =
|
|
|
|
|
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
|
|
|
|
|
if (result.IsError()) {
|
|
|
|
@@ -1063,11 +1063,11 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
|
|
|
|
|
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
|
|
|
|
for (u32 i = 0; i < symbol_import_num; ++i) {
|
|
|
|
|
ImportNamedSymbolEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
|
|
|
|
ExternalRelocationEntry relocation_entry;
|
|
|
|
|
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
|
|
|
|
sizeof(ExternalRelocationEntry));
|
|
|
|
|
|
|
|
|
|
if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
|
|
|
|
|
ResultCode result = ForEachAutoLinkCRO(
|
|
|
|
@@ -1266,11 +1266,11 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
|
|
|
|
|
// so we do the same
|
|
|
|
|
if (GetField(SegmentNum) >= 2) { // means we have .data segment
|
|
|
|
|
SegmentEntry entry;
|
|
|
|
|
GetEntry(2, entry);
|
|
|
|
|
GetEntry(memory, 2, entry);
|
|
|
|
|
ASSERT(entry.type == SegmentType::Data);
|
|
|
|
|
data_segment_address = entry.offset;
|
|
|
|
|
entry.offset = GetField(DataOffset);
|
|
|
|
|
SetEntry(2, entry);
|
|
|
|
|
SetEntry(memory, 2, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
SCOPE_EXIT({
|
|
|
|
@@ -1278,9 +1278,9 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
|
|
|
|
|
if (link_on_load_bug_fix) {
|
|
|
|
|
if (GetField(SegmentNum) >= 2) {
|
|
|
|
|
SegmentEntry entry;
|
|
|
|
|
GetEntry(2, entry);
|
|
|
|
|
GetEntry(memory, 2, entry);
|
|
|
|
|
entry.offset = data_segment_address;
|
|
|
|
|
SetEntry(2, entry);
|
|
|
|
|
SetEntry(memory, 2, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@@ -1516,7 +1516,7 @@ std::tuple<VAddr, u32> CROHelper::GetExecutablePages() const {
|
|
|
|
|
u32 segment_num = GetField(SegmentNum);
|
|
|
|
|
for (u32 i = 0; i < segment_num; ++i) {
|
|
|
|
|
SegmentEntry entry;
|
|
|
|
|
GetEntry(i, entry);
|
|
|
|
|
GetEntry(memory, i, entry);
|
|
|
|
|
if (entry.type == SegmentType::Code && entry.size != 0) {
|
|
|
|
|
VAddr begin = Common::AlignDown(entry.offset, Memory::PAGE_SIZE);
|
|
|
|
|
VAddr end = Common::AlignUp(entry.offset + entry.size, Memory::PAGE_SIZE);
|
|
|
|
|