From 6ee944a0a639d00be24f1f40172673f15ec2fcee Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 16 Apr 2021 00:41:56 -0700 Subject: [PATCH] Module: Process relocations on threads. There's usually quite some, and using threads can halve the load time. ELF loading isn't terribly slow, but it adds up. --- Core/ELF/ElfReader.cpp | 145 ++++++++++++++++++----------------- Core/HLE/sceKernelModule.cpp | 2 +- 2 files changed, 74 insertions(+), 73 deletions(-) diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index 4cc55de21a..410bbb8d6d 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -17,6 +17,7 @@ #include "Core/MemMap.h" #include "Core/Reporting.h" +#include "Core/ThreadPools.h" #include "Core/MIPS/MIPSTables.h" #include "Core/ELF/ElfReader.h" #include "Core/Debugger/MemBlockInfo.h" @@ -57,83 +58,80 @@ bool ElfReader::LoadRelocations(const Elf32_Rel *rels, int numRelocs) { int numErrors = 0; DEBUG_LOG(LOADER, "Loading %i relocations...", numRelocs); - for (int r = 0; r < numRelocs; r++) - { - // INFO_LOG(LOADER, "Loading reloc %i (%p)...", r, rels + r); - u32 info = rels[r].r_info; - u32 addr = rels[r].r_offset; + GlobalThreadPool::Loop([&](int l, int h) { + for (int r = l; r < h; r++) { + VERBOSE_LOG(LOADER, "Loading reloc %i (%p)...", r, rels + r); + u32 info = rels[r].r_info; + u32 addr = rels[r].r_offset; - int type = info & 0xf; + int type = info & 0xf; - int readwrite = (info>>8) & 0xff; - int relative = (info>>16) & 0xff; + int readwrite = (info >> 8) & 0xff; + int relative = (info >> 16) & 0xff; - //0 = code - //1 = data + //0 = code + //1 = data - if (readwrite >= (int)ARRAY_SIZE(segmentVAddr)) { - if (numErrors < 10) { - ERROR_LOG_REPORT(LOADER, "Bad segment number %i", readwrite); + if (readwrite >= (int)ARRAY_SIZE(segmentVAddr)) { + if (numErrors < 10) { + ERROR_LOG_REPORT(LOADER, "Bad segment number %i", readwrite); + } + numErrors++; + continue; } - numErrors++; - continue; - } - addr += segmentVAddr[readwrite]; + addr += segmentVAddr[readwrite]; - // It appears that misaligned relocations are allowed. - // Will they work correctly on big-endian? + // It appears that misaligned relocations are allowed. + // Will they work correctly on big-endian? - if (((addr & 3) && type != R_MIPS_32) || !Memory::IsValidAddress(addr)) { - if (numErrors < 10) { - WARN_LOG_REPORT(LOADER, "Suspicious address %08x, skipping reloc, type = %d", addr, type); - } else if (numErrors == 10) { - WARN_LOG(LOADER, "Too many bad relocations, skipping logging"); + if (((addr & 3) && type != R_MIPS_32) || !Memory::IsValidAddress(addr)) { + if (numErrors < 10) { + WARN_LOG_REPORT(LOADER, "Suspicious address %08x, skipping reloc, type = %d", addr, type); + } else if (numErrors == 10) { + WARN_LOG(LOADER, "Too many bad relocations, skipping logging"); + } + numErrors++; + continue; } - numErrors++; - continue; - } - u32 op = Memory::ReadUnchecked_Instruction(addr, true).encoding; + u32 op = Memory::ReadUnchecked_Instruction(addr, true).encoding; - const bool log = false; - //log=true; - if (log) { - DEBUG_LOG(LOADER,"rel at: %08x info: %08x type: %i",addr, info, type); - } - u32 relocateTo = segmentVAddr[relative]; + const bool log = false; + //log=true; + if (log) { + DEBUG_LOG(LOADER, "rel at: %08x info: %08x type: %i", addr, info, type); + } + u32 relocateTo = segmentVAddr[relative]; - switch (type) - { - case R_MIPS_32: - if (log) - DEBUG_LOG(LOADER,"Full address reloc %08x", addr); - //full address, no problemo - op += relocateTo; - break; + switch (type) { + case R_MIPS_32: + if (log) + DEBUG_LOG(LOADER, "Full address reloc %08x", addr); + //full address, no problemo + op += relocateTo; + break; - case R_MIPS_26: //j, jal - //add on to put in correct address space - if (log) - DEBUG_LOG(LOADER,"j/jal reloc %08x", addr); - op = (op & 0xFC000000) | (((op&0x03FFFFFF)+(relocateTo>>2))&0x03FFFFFF); - break; + case R_MIPS_26: //j, jal + //add on to put in correct address space + if (log) + DEBUG_LOG(LOADER, "j/jal reloc %08x", addr); + op = (op & 0xFC000000) | (((op & 0x03FFFFFF) + (relocateTo >> 2)) & 0x03FFFFFF); + break; - case R_MIPS_HI16: //lui part of lui-addiu pairs + case R_MIPS_HI16: //lui part of lui-addiu pairs { if (log) - DEBUG_LOG(LOADER,"HI reloc %08x", addr); + DEBUG_LOG(LOADER, "HI reloc %08x", addr); u32 cur = (op & 0xFFFF) << 16; u16 hi = 0; bool found = false; - for (int t = r + 1; t