LDR fixup !=0

This commit is contained in:
wwylele 2016-08-16 11:34:33 +08:00
parent 1dfb4686e6
commit 0cec1cf59b

View File

@ -384,7 +384,7 @@ class CROHelper final {
template <typename FunctionObject> template <typename FunctionObject>
static ResultCode ForEachAutoLinkCRO(VAddr crs_address, FunctionObject func) { static ResultCode ForEachAutoLinkCRO(VAddr crs_address, FunctionObject func) {
VAddr current = crs_address; VAddr current = crs_address;
while (current) { while (current != 0) {
CROHelper cro(current); CROHelper cro(current);
CASCADE_RESULT(bool next, func(cro)); CASCADE_RESULT(bool next, func(cro));
if (!next) if (!next)
@ -560,7 +560,7 @@ class CROHelper final {
return error; return error;
// verifies not registered // verifies not registered
if (GetField(NextCRO) || GetField(PreviousCRO)) if (GetField(NextCRO) != 0 || GetField(PreviousCRO) != 0)
return error; return error;
// This seems to be a hard limit set by the RO module // This seems to be a hard limit set by the RO module
@ -568,7 +568,7 @@ class CROHelper final {
return error; return error;
// verifies not fixed // verifies not fixed
if (GetField(FixedSize)) if (GetField(FixedSize) != 0)
return error; return error;
if (GetField(CodeOffset) < CRO_HEADER_SIZE) if (GetField(CodeOffset) < CRO_HEADER_SIZE)
@ -607,13 +607,13 @@ class CROHelper final {
// rebases offsets // rebases offsets
u32 offset = GetField(NameOffset); u32 offset = GetField(NameOffset);
if (offset) if (offset != 0)
SetField(NameOffset, offset + module_address); SetField(NameOffset, offset + module_address);
for (int field = CodeOffset; field < Fix0Barrier; field += 2) { for (int field = CodeOffset; field < Fix0Barrier; field += 2) {
HeaderField header_field = static_cast<HeaderField>(field); HeaderField header_field = static_cast<HeaderField>(field);
offset = GetField(header_field); offset = GetField(header_field);
if (offset) if (offset != 0)
SetField(header_field, offset + module_address); SetField(header_field, offset + module_address);
} }
@ -636,7 +636,7 @@ class CROHelper final {
* @returns ResultCode RESULT_SUCCESS if the size matches, otherwise error code. * @returns ResultCode RESULT_SUCCESS if the size matches, otherwise error code.
*/ */
static ResultCode VerifyString(VAddr address, u32 size) { static ResultCode VerifyString(VAddr address, u32 size) {
if (size) { if (size != 0) {
if (Memory::Read8(address + size - 1) != 0) if (Memory::Read8(address + size - 1) != 0)
return CROFormatError(0x0B); return CROFormatError(0x0B);
} }
@ -661,19 +661,19 @@ class CROHelper final {
SegmentEntry segment; SegmentEntry segment;
GetEntry(i, segment); GetEntry(i, segment);
if (segment.type == SegmentType::Data) { if (segment.type == SegmentType::Data) {
if (segment.size) { if (segment.size != 0) {
if (segment.size > data_segment_size) if (segment.size > data_segment_size)
return ERROR_BUFFER_TOO_SMALL; return ERROR_BUFFER_TOO_SMALL;
prev_data_segment = segment.offset; prev_data_segment = segment.offset;
segment.offset = data_segment_address; segment.offset = data_segment_address;
} }
} else if (segment.type == SegmentType::BSS) { } else if (segment.type == SegmentType::BSS) {
if (segment.size) { if (segment.size != 0) {
if (segment.size > bss_segment_size) if (segment.size > bss_segment_size)
return ERROR_BUFFER_TOO_SMALL; return ERROR_BUFFER_TOO_SMALL;
segment.offset = bss_segment_address; segment.offset = bss_segment_address;
} }
} else if (segment.offset) { } else if (segment.offset != 0) {
segment.offset += module_address; segment.offset += module_address;
if (segment.offset > module_address + cro_size) if (segment.offset > module_address + cro_size)
return CROFormatError(0x19); return CROFormatError(0x19);
@ -696,7 +696,7 @@ class CROHelper final {
ExportNamedSymbolEntry entry; ExportNamedSymbolEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.name_offset) { if (entry.name_offset != 0) {
entry.name_offset += module_address; entry.name_offset += module_address;
if (entry.name_offset < export_strings_offset if (entry.name_offset < export_strings_offset
|| entry.name_offset >= export_strings_end) { || entry.name_offset >= export_strings_end) {
@ -743,7 +743,7 @@ class CROHelper final {
ImportModuleEntry entry; ImportModuleEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.name_offset) { if (entry.name_offset != 0) {
entry.name_offset += module_address; entry.name_offset += module_address;
if (entry.name_offset < import_strings_offset if (entry.name_offset < import_strings_offset
|| entry.name_offset >= import_strings_end) { || entry.name_offset >= import_strings_end) {
@ -751,7 +751,7 @@ class CROHelper final {
} }
} }
if (entry.import_indexed_symbol_table_offset) { if (entry.import_indexed_symbol_table_offset != 0) {
entry.import_indexed_symbol_table_offset += module_address; entry.import_indexed_symbol_table_offset += module_address;
if (entry.import_indexed_symbol_table_offset < import_indexed_symbol_table_offset if (entry.import_indexed_symbol_table_offset < import_indexed_symbol_table_offset
|| entry.import_indexed_symbol_table_offset > index_import_table_end) { || entry.import_indexed_symbol_table_offset > index_import_table_end) {
@ -759,7 +759,7 @@ class CROHelper final {
} }
} }
if (entry.import_anonymous_symbol_table_offset) { if (entry.import_anonymous_symbol_table_offset != 0) {
entry.import_anonymous_symbol_table_offset += module_address; entry.import_anonymous_symbol_table_offset += module_address;
if (entry.import_anonymous_symbol_table_offset < import_anonymous_symbol_table_offset if (entry.import_anonymous_symbol_table_offset < import_anonymous_symbol_table_offset
|| entry.import_anonymous_symbol_table_offset > offset_import_table_end) { || entry.import_anonymous_symbol_table_offset > offset_import_table_end) {
@ -787,7 +787,7 @@ class CROHelper final {
ImportNamedSymbolEntry entry; ImportNamedSymbolEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.name_offset) { if (entry.name_offset != 0) {
entry.name_offset += module_address; entry.name_offset += module_address;
if (entry.name_offset < import_strings_offset if (entry.name_offset < import_strings_offset
|| entry.name_offset >= import_strings_end) { || entry.name_offset >= import_strings_end) {
@ -795,7 +795,7 @@ class CROHelper final {
} }
} }
if (entry.patch_batch_offset) { if (entry.patch_batch_offset != 0) {
entry.patch_batch_offset += module_address; entry.patch_batch_offset += module_address;
if (entry.patch_batch_offset < external_patch_table_offset if (entry.patch_batch_offset < external_patch_table_offset
|| entry.patch_batch_offset > external_patch_table_end) { || entry.patch_batch_offset > external_patch_table_end) {
@ -821,7 +821,7 @@ class CROHelper final {
ImportIndexedSymbolEntry entry; ImportIndexedSymbolEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.patch_batch_offset) { if (entry.patch_batch_offset != 0) {
entry.patch_batch_offset += module_address; entry.patch_batch_offset += module_address;
if (entry.patch_batch_offset < external_patch_table_offset if (entry.patch_batch_offset < external_patch_table_offset
|| entry.patch_batch_offset > external_patch_table_end) { || entry.patch_batch_offset > external_patch_table_end) {
@ -847,7 +847,7 @@ class CROHelper final {
ImportAnonymousSymbolEntry entry; ImportAnonymousSymbolEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.patch_batch_offset) { if (entry.patch_batch_offset != 0) {
entry.patch_batch_offset += module_address; entry.patch_batch_offset += module_address;
if (entry.patch_batch_offset < external_patch_table_offset if (entry.patch_batch_offset < external_patch_table_offset
|| entry.patch_batch_offset > external_patch_table_end) { || entry.patch_batch_offset > external_patch_table_end) {
@ -1055,7 +1055,7 @@ class CROHelper final {
ImportAnonymousSymbolEntry entry; ImportAnonymousSymbolEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.patch_batch_offset) { if (entry.patch_batch_offset != 0) {
entry.patch_batch_offset -= module_address; entry.patch_batch_offset -= module_address;
} }
@ -1070,7 +1070,7 @@ class CROHelper final {
ImportIndexedSymbolEntry entry; ImportIndexedSymbolEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.patch_batch_offset) { if (entry.patch_batch_offset != 0) {
entry.patch_batch_offset -= module_address; entry.patch_batch_offset -= module_address;
} }
@ -1085,7 +1085,7 @@ class CROHelper final {
ImportNamedSymbolEntry entry; ImportNamedSymbolEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.name_offset) { if (entry.name_offset != 0) {
entry.name_offset -= module_address; entry.name_offset -= module_address;
} }
@ -1104,7 +1104,7 @@ class CROHelper final {
ImportModuleEntry entry; ImportModuleEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.name_offset) { if (entry.name_offset != 0) {
entry.name_offset -= module_address; entry.name_offset -= module_address;
} }
@ -1127,7 +1127,7 @@ class CROHelper final {
ExportNamedSymbolEntry entry; ExportNamedSymbolEntry entry;
GetEntry(i, entry); GetEntry(i, entry);
if (entry.name_offset) { if (entry.name_offset != 0) {
entry.name_offset -= module_address; entry.name_offset -= module_address;
} }
@ -1144,7 +1144,7 @@ class CROHelper final {
if (segment.type == SegmentType::BSS) { if (segment.type == SegmentType::BSS) {
segment.offset = 0; segment.offset = 0;
} else if (segment.offset) { } else if (segment.offset != 0) {
segment.offset -= module_address; segment.offset -= module_address;
} }
@ -1155,13 +1155,13 @@ class CROHelper final {
/// Unrebases offsets in module header /// Unrebases offsets in module header
void UnrebaseHeader() { void UnrebaseHeader() {
u32 offset = GetField(NameOffset); u32 offset = GetField(NameOffset);
if (offset) if (offset != 0)
SetField(NameOffset, offset - module_address); SetField(NameOffset, offset - module_address);
for (int field = CodeOffset; field < Fix0Barrier; field += 2) { for (int field = CodeOffset; field < Fix0Barrier; field += 2) {
HeaderField header_field = static_cast<HeaderField>(field); HeaderField header_field = static_cast<HeaderField>(field);
offset = GetField(header_field); offset = GetField(header_field);
if (offset) if (offset != 0)
SetField(header_field, offset - module_address); SetField(header_field, offset - module_address);
} }
} }
@ -1186,7 +1186,7 @@ class CROHelper final {
std::string symbol_name = Memory::ReadCString(entry.name_offset, import_strings_size); std::string symbol_name = Memory::ReadCString(entry.name_offset, import_strings_size);
u32 symbol_address = source.FindExportNamedSymbol(symbol_name); u32 symbol_address = source.FindExportNamedSymbol(symbol_name);
if (symbol_address) { if (symbol_address != 0) {
LOG_TRACE(Service_LDR, "CRO \"%s\" imports \"%s\" from \"%s\"", LOG_TRACE(Service_LDR, "CRO \"%s\" imports \"%s\" from \"%s\"",
ModuleName().data(), symbol_name.data(), source.ModuleName().data()); ModuleName().data(), symbol_name.data(), source.ModuleName().data());
@ -1357,7 +1357,7 @@ class CROHelper final {
if (!patch_entry.is_batch_resolved) { if (!patch_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); u32 symbol_address = FindExportNamedSymbol(symbol_name);
if (symbol_address) { if (symbol_address != 0) {
LOG_TRACE(Service_LDR, " exports symbol \"%s\"", symbol_name.data()); LOG_TRACE(Service_LDR, " exports symbol \"%s\"", symbol_name.data());
ResultCode result = target.ApplyPatchBatch(patch_addr, symbol_address); ResultCode result = target.ApplyPatchBatch(patch_addr, symbol_address);
if (result.IsError()) { if (result.IsError()) {
@ -1391,7 +1391,7 @@ class CROHelper final {
if (patch_entry.is_batch_resolved) { if (patch_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); u32 symbol_address = FindExportNamedSymbol(symbol_name);
if (symbol_address) { if (symbol_address != 0) {
LOG_TRACE(Service_LDR, " unexports symbol \"%s\"", symbol_name.data()); LOG_TRACE(Service_LDR, " unexports symbol \"%s\"", symbol_name.data());
ResultCode result = target.ApplyPatchBatch(patch_addr, unresolved_symbol, true); ResultCode result = target.ApplyPatchBatch(patch_addr, unresolved_symbol, true);
if (result.IsError()) { if (result.IsError()) {
@ -1519,7 +1519,7 @@ class CROHelper final {
ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> {
u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_");
if (symbol_address) { if (symbol_address != 0) {
LOG_DEBUG(Service_LDR, "CRO \"%s\" import exit function from \"%s\"", LOG_DEBUG(Service_LDR, "CRO \"%s\" import exit function from \"%s\"",
ModuleName().data(), source.ModuleName().data()); ModuleName().data(), source.ModuleName().data());
@ -2142,7 +2142,7 @@ static void Initialize(Service::Interface* self) {
cmd_buff[0] = IPC::MakeHeader(1, 1, 0); cmd_buff[0] = IPC::MakeHeader(1, 1, 0);
if (loaded_crs) { if (loaded_crs != 0) {
LOG_ERROR(Service_LDR, "Already initialized"); LOG_ERROR(Service_LDR, "Already initialized");
cmd_buff[1] = ERROR_ALREADY_INITIALIZED.raw; cmd_buff[1] = ERROR_ALREADY_INITIALIZED.raw;
return; return;
@ -2354,7 +2354,7 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
cmd_buff[0] = IPC::MakeHeader(link_on_load_bug_fix ? 9 : 4, 2, 0); cmd_buff[0] = IPC::MakeHeader(link_on_load_bug_fix ? 9 : 4, 2, 0);
if (!loaded_crs) { if (loaded_crs == 0) {
LOG_ERROR(Service_LDR, "Not initialized"); LOG_ERROR(Service_LDR, "Not initialized");
cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; cmd_buff[1] = ERROR_NOT_INITIALIZED.raw;
return; return;
@ -2545,7 +2545,7 @@ static void UnloadCRO(Service::Interface* self) {
cmd_buff[0] = IPC::MakeHeader(5, 1, 0); cmd_buff[0] = IPC::MakeHeader(5, 1, 0);
if (!loaded_crs) { if (loaded_crs == 0) {
LOG_ERROR(Service_LDR, "Not initialized"); LOG_ERROR(Service_LDR, "Not initialized");
cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; cmd_buff[1] = ERROR_NOT_INITIALIZED.raw;
return; return;
@ -2637,7 +2637,7 @@ static void LinkCRO(Service::Interface* self) {
cmd_buff[0] = IPC::MakeHeader(6, 1, 0); cmd_buff[0] = IPC::MakeHeader(6, 1, 0);
if (!loaded_crs) { if (loaded_crs == 0) {
LOG_ERROR(Service_LDR, "Not initialized"); LOG_ERROR(Service_LDR, "Not initialized");
cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; cmd_buff[1] = ERROR_NOT_INITIALIZED.raw;
return; return;
@ -2700,7 +2700,7 @@ static void UnlinkCRO(Service::Interface* self) {
cmd_buff[0] = IPC::MakeHeader(7, 1, 0); cmd_buff[0] = IPC::MakeHeader(7, 1, 0);
if (!loaded_crs) { if (loaded_crs == 0) {
LOG_ERROR(Service_LDR, "Not initialized"); LOG_ERROR(Service_LDR, "Not initialized");
cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; cmd_buff[1] = ERROR_NOT_INITIALIZED.raw;
return; return;
@ -2759,7 +2759,7 @@ static void Shutdown(Service::Interface* self) {
memory_synchronizer.SynchronizeMappingMemory(); memory_synchronizer.SynchronizeMappingMemory();
if (!loaded_crs) { if (loaded_crs == 0) {
LOG_ERROR(Service_LDR, "Not initialized"); LOG_ERROR(Service_LDR, "Not initialized");
cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; cmd_buff[1] = ERROR_NOT_INITIALIZED.raw;
return; return;