diff --git a/rpcsx-os/linker.cpp b/rpcsx-os/linker.cpp index 90df7a09..a6724491 100644 --- a/rpcsx-os/linker.cpp +++ b/rpcsx-os/linker.cpp @@ -373,7 +373,7 @@ Ref rx::linker::loadModule(std::span image, header.e_phnum * sizeof(Elf64_Phdr)); auto phdrs = std::span(phdrsStorage, header.e_phnum); - std::uint64_t imageSize = 0; + std::uint64_t endAddress = 0; std::uint64_t baseAddress = ~static_cast(0); int dynamicPhdrIndex = -1; int interpPhdrIndex = -1; @@ -399,8 +399,9 @@ Ref rx::linker::loadModule(std::span image, case kElfProgramTypeLoad: baseAddress = std::min(baseAddress, utils::alignDown(phdr.p_vaddr, phdr.p_align)); - imageSize = std::max( - imageSize, utils::alignUp(phdr.p_vaddr + phdr.p_memsz, phdr.p_align)); + endAddress = + std::max(endAddress, + utils::alignUp(phdr.p_vaddr + phdr.p_memsz, phdr.p_align)); break; case kElfProgramTypeDynamic: dynamicPhdrIndex = index; @@ -433,8 +434,9 @@ Ref rx::linker::loadModule(std::span image, sceRelRoPhdrIndex = index; baseAddress = std::min(baseAddress, utils::alignDown(phdr.p_vaddr, phdr.p_align)); - imageSize = std::max( - imageSize, utils::alignUp(phdr.p_vaddr + phdr.p_memsz, phdr.p_align)); + endAddress = + std::max(endAddress, + utils::alignUp(phdr.p_vaddr + phdr.p_memsz, phdr.p_align)); break; case kElfProgramTypeGnuEhFrame: gnuEhFramePhdrIndex = index; @@ -451,24 +453,27 @@ Ref rx::linker::loadModule(std::span image, } } + auto imageSize = endAddress - baseAddress; + auto imageBase = reinterpret_cast( rx::vm::map(reinterpret_cast(baseAddress), utils::alignUp(imageSize, rx::vm::kPageSize), 0, - rx::vm::kMapFlagPrivate | rx::vm::kMapFlagAnonymous)); + rx::vm::kMapFlagPrivate | rx::vm::kMapFlagAnonymous | + (baseAddress ? rx::vm::kMapFlagFixed : 0))); if (imageBase == MAP_FAILED) { std::abort(); } - result->entryPoint = - header.e_entry - ? reinterpret_cast(imageBase + header.e_entry) - : 0; + result->entryPoint = header.e_entry + ? reinterpret_cast( + imageBase - baseAddress + header.e_entry) + : 0; if (sceProcParamIndex >= 0) { result->processParam = phdrs[sceProcParamIndex].p_vaddr - ? reinterpret_cast(imageBase + + ? reinterpret_cast(imageBase - baseAddress + phdrs[sceProcParamIndex].p_vaddr) : nullptr; result->processParamSize = phdrs[sceProcParamIndex].p_memsz; @@ -477,7 +482,7 @@ Ref rx::linker::loadModule(std::span image, if (sceModuleParamIndex >= 0) { result->moduleParam = phdrs[sceModuleParamIndex].p_vaddr - ? reinterpret_cast(imageBase + + ? reinterpret_cast(imageBase - baseAddress + phdrs[sceModuleParamIndex].p_vaddr) : nullptr; result->moduleParamSize = phdrs[sceModuleParamIndex].p_memsz; @@ -495,12 +500,12 @@ Ref rx::linker::loadModule(std::span image, result->tlsSize = phdrs[tlsPhdrIndex].p_memsz; result->tlsInitSize = phdrs[tlsPhdrIndex].p_filesz; result->tlsInit = phdrs[tlsPhdrIndex].p_vaddr - ? imageBase + phdrs[tlsPhdrIndex].p_vaddr + ? imageBase - baseAddress + phdrs[tlsPhdrIndex].p_vaddr : nullptr; } if (gnuEhFramePhdrIndex >= 0 && phdrs[gnuEhFramePhdrIndex].p_vaddr > 0) { - result->ehFrameHdr = imageBase + phdrs[gnuEhFramePhdrIndex].p_vaddr; + result->ehFrameHdr = imageBase - baseAddress + phdrs[gnuEhFramePhdrIndex].p_vaddr; result->ehFrameHdrSize = phdrs[gnuEhFramePhdrIndex].p_memsz; struct GnuExceptionInfo { @@ -530,7 +535,7 @@ Ref rx::linker::loadModule(std::span image, if (exinfo->encoding == 0x03) { auto offset = *reinterpret_cast(&exinfo->first); - dataBuffer = imageBase + offset; + dataBuffer = imageBase - baseAddress + offset; } else if (exinfo->encoding == 0x1B) { auto offset = *reinterpret_cast(&exinfo->first); dataBuffer = &exinfo->first + sizeof(std::int32_t) + offset; @@ -556,7 +561,7 @@ Ref rx::linker::loadModule(std::span image, } result->ehFrame = - imageBase + phdrs[gnuEhFramePhdrIndex].p_vaddr + + imageBase - baseAddress + phdrs[gnuEhFramePhdrIndex].p_vaddr + (dataBuffer - image.data() - phdrs[gnuEhFramePhdrIndex].p_offset); result->ehFrameSize = dataBufferIt - dataBuffer; } @@ -721,7 +726,7 @@ Ref rx::linker::loadModule(std::span image, case kElfDynamicTypeScePltGot: result->pltGot = dyn.d_un.d_ptr - ? reinterpret_cast(imageBase + dyn.d_un.d_ptr) + ? reinterpret_cast(imageBase - baseAddress + dyn.d_un.d_ptr) : nullptr; break; @@ -749,10 +754,10 @@ Ref rx::linker::loadModule(std::span image, break; case kElfDynamicTypeInit: - result->initProc = imageBase + dyn.d_un.d_ptr; + result->initProc = imageBase - baseAddress + dyn.d_un.d_ptr; break; case kElfDynamicTypeFini: - result->finiProc = imageBase + dyn.d_un.d_ptr; + result->finiProc = imageBase - baseAddress + dyn.d_un.d_ptr; break; } } @@ -836,17 +841,19 @@ Ref rx::linker::loadModule(std::span image, if (phdr.p_type == kElfProgramTypeLoad || phdr.p_type == kElfProgramTypeSceRelRo) { auto segmentSize = utils::alignUp(phdr.p_memsz, phdr.p_align); - ::mprotect(imageBase + phdr.p_vaddr, segmentSize, PROT_WRITE); - std::memcpy(imageBase + phdr.p_vaddr, image.data() + phdr.p_offset, - phdr.p_filesz); - std::memset(imageBase + phdr.p_vaddr + phdr.p_filesz, 0, + ::mprotect(imageBase + phdr.p_vaddr - baseAddress, segmentSize, + PROT_WRITE); + std::memcpy(imageBase + phdr.p_vaddr - baseAddress, + image.data() + phdr.p_offset, phdr.p_filesz); + std::memset(imageBase + phdr.p_vaddr + phdr.p_filesz - baseAddress, 0, phdr.p_memsz - phdr.p_filesz); if (phdr.p_type == kElfProgramTypeSceRelRo) { phdr.p_flags |= vm::kMapProtCpuWrite; // TODO: reprotect on relocations } - vm::protect(imageBase + phdr.p_vaddr, segmentSize, phdr.p_flags); + vm::protect(imageBase + phdr.p_vaddr - baseAddress, segmentSize, + phdr.p_flags); if (phdr.p_type == kElfProgramTypeLoad) { if (result->segmentCount >= std::size(result->segments)) { @@ -854,7 +861,7 @@ Ref rx::linker::loadModule(std::span image, } auto &segment = result->segments[result->segmentCount++]; - segment.addr = imageBase + phdr.p_vaddr; + segment.addr = imageBase + phdr.p_vaddr - baseAddress; segment.size = phdr.p_memsz; segment.prot = phdr.p_flags; } @@ -960,8 +967,9 @@ Ref rx::linker::loadModuleFile(std::string_view path, if (image[0] != std::byte{'\x7f'} || image[1] != std::byte{'E'} || image[2] != std::byte{'L'} || image[3] != std::byte{'F'}) { image = unself(image.data(), image.size()); - - std::ofstream("a.out", std::ios::binary).write((const char *)image.data(), image.size()); + + std::ofstream("a.out", std::ios::binary) + .write((const char *)image.data(), image.size()); } return loadModule(image, thread->tproc); diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index cb3dc5e6..897c7168 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -250,7 +250,7 @@ static const char *getSyscallName(orbis::Thread *thread, int sysno) { } static void onSysEnter(orbis::Thread *thread, int id, uint64_t *args, int argsCount) { - if (true || !g_traceSyscalls) { + if (!g_traceSyscalls) { return; } flockfile(stderr); @@ -400,8 +400,8 @@ static int ps4Exec(orbis::Thread *mainThread, // *reinterpret_cast( // reinterpret_cast(libkernel->base) + 0x6c2e4) = ~0; - *reinterpret_cast( - reinterpret_cast(libkernel->base) + 0x71300) = ~0; + // *reinterpret_cast( + // reinterpret_cast(libkernel->base) + 0x71300) = ~0; StackWriter stack{reinterpret_cast(mainThread->stackEnd)}; @@ -731,7 +731,8 @@ int main(int argc, const char *argv[]) { initProcess->processParamSize = executableModule->processParamSize; if (executableModule->type == rx::linker::kElfTypeSceDynExec || - executableModule->type == rx::linker::kElfTypeSceExec) { + executableModule->type == rx::linker::kElfTypeSceExec || + executableModule->type == rx::linker::kElfTypeExec) { status = ps4Exec(mainThread, std::move(executableModule), std::span(argv + argIndex, argc - argIndex), std::span());