From f5ad20ae72f40f02597f6e6e1f0dc5378fbbbbbd Mon Sep 17 00:00:00 2001 From: SysRay Date: Sat, 18 May 2024 20:20:26 +0200 Subject: [PATCH 1/5] directMem query fix --- core/dmem/types/directmem.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/dmem/types/directmem.cpp b/core/dmem/types/directmem.cpp index c135cdf5..34a95b4f 100644 --- a/core/dmem/types/directmem.cpp +++ b/core/dmem/types/directmem.cpp @@ -27,7 +27,7 @@ enum class MemoryState { Commited, }; -struct MemoryMapping { +struct MemoryMappingDirect { uint64_t addr = 0; uint64_t heapAddr = 0; // addr for MemoryInfo @@ -83,8 +83,8 @@ class DirectMemory: public IMemoryType { IMemoryManager* m_parent; - std::map m_objects; - std::map m_mappings; + std::map m_objects; + std::map m_mappings; uint64_t m_allocSize = 0; uint64_t m_usedSize = 0; @@ -355,7 +355,7 @@ int DirectMemory::map(uint64_t vaddr, off_t offset, size_t len, int prot, int fl *outAddr = (uint64_t)info->allocAddr + fakeAddrOffset; m_mappings.emplace( - std::make_pair(*outAddr, MemoryMapping {.addr = *outAddr, .heapAddr = info->addr, .size = len, .alignment = alignment, .vmaAlloc = alloc})); + std::make_pair(*outAddr, MemoryMappingDirect {.addr = *outAddr, .heapAddr = info->addr, .size = len, .alignment = alignment, .vmaAlloc = alloc})); m_parent->registerMapping(*outAddr, len, MappingType::Direct); m_usedSize += len; @@ -499,7 +499,7 @@ int32_t DirectMemory::virtualQuery(uint64_t addr, SceKernelVirtualQueryInfo* inf auto itMapping = m_mappings.lower_bound(addr); if (itMapping == m_mappings.end() || (itMapping != m_mappings.begin() && itMapping->first != addr)) --itMapping; // Get the correct item - if (!(itMapping->first <= addr && (itMapping->first + itMapping->second.size >= addr))) { + if (!(itMapping->first <= addr && (itMapping->first + itMapping->second.size > addr))) { if (itItem->second.state == MemoryState::Reserved) { info->start = (void*)itItem->first; info->end = (void*)(itItem->first + itItem->second.size); From dd2d60d2beb304f618818b30fcb517b1ffa4bef2 Mon Sep 17 00:00:00 2001 From: SysRay Date: Thu, 23 May 2024 12:44:39 +0200 Subject: [PATCH 2/5] runtime| fix modulinfo --- core/runtime/runtimeExport.h | 4 ++-- core/runtime/runtimeLinker.cpp | 2 +- modules/libkernel/entry.cpp | 11 +++++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/core/runtime/runtimeExport.h b/core/runtime/runtimeExport.h index d423d031..925b8e98 100644 --- a/core/runtime/runtimeExport.h +++ b/core/runtime/runtimeExport.h @@ -21,8 +21,8 @@ struct alignas(32) EntryParams { }; struct ModulInfo { - uint64_t address; - uint64_t size; + uint64_t seg0Addr; + uint64_t seg0Size; uint64_t procParamAddr; }; diff --git a/core/runtime/runtimeLinker.cpp b/core/runtime/runtimeLinker.cpp index f0850b2e..49ed6a89 100644 --- a/core/runtime/runtimeLinker.cpp +++ b/core/runtime/runtimeLinker.cpp @@ -302,7 +302,7 @@ class RuntimeLinker: public IRuntimeLinker { ModulInfo mainModuleInfo() const final { auto prog = accessMainProg(); - return {prog->baseVaddr, prog->baseSize, prog->procParamVaddr}; + return {prog->moduleInfoEx.segments[0].address, prog->moduleInfoEx.segments[0].size, prog->procParamVaddr}; } SceKernelModuleInfoEx const* getModuleInfoEx(uint64_t vaddr) const final { diff --git a/modules/libkernel/entry.cpp b/modules/libkernel/entry.cpp index a6bebad2..c28bba0b 100644 --- a/modules/libkernel/entry.cpp +++ b/modules/libkernel/entry.cpp @@ -100,10 +100,17 @@ EXPORT SYSV_ABI void* _sceModuleParam() { return reinterpret_cast(procParamVaddr); } -EXPORT SYSV_ABI int sceKernelInternalMemoryGetModuleSegmentInfo(ModulInfo* info) { +struct ModuleSegmentInfo { + uint64_t addr; + uint64_t size; +}; + +EXPORT SYSV_ABI int sceKernelInternalMemoryGetModuleSegmentInfo(ModuleSegmentInfo* info) { if (info == nullptr) return getErr(ErrCode::_EFAULT); - *info = accessRuntimeLinker().mainModuleInfo(); + auto mainInfo = accessRuntimeLinker().mainModuleInfo(); + info->addr = mainInfo.seg0Addr; + info->size = mainInfo.seg0Size; return Ok; } From a1d90205923e7e1d8b4a5d0edf5f431ecedb57aa Mon Sep 17 00:00:00 2001 From: SysRay Date: Sun, 26 May 2024 15:24:29 +0200 Subject: [PATCH 3/5] main| fix procparam access --- main.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/main.cpp b/main.cpp index a2d9a0c2..2023e3fc 100644 --- a/main.cpp +++ b/main.cpp @@ -187,12 +187,13 @@ int main(int argc, char** argv) { } // --- modules + auto mainProg = accessRuntimeLinker().accessMainProg(); auto* procParam = (ProcParam*)accessRuntimeLinker().accessMainProg()->procParamVaddr; // Set flexiblememory size if available - if (procParam->header.size < (8 + offsetof(ProcParam, PSceLibcParam))) { - auto memparam = procParam->_sceKernelMemParam; - if (memparam != 0 && memparam->sceKernelFlexibleMemorySize != nullptr) { + if (procParam->header.size > (8 + offsetof(ProcParam, PSceLibcParam))) { + auto memparam = (SceKernelMemParam*)((uint64_t)procParam->_sceKernelMemParam + mainProg->baseVaddr); + if (procParam->_sceKernelMemParam != 0 && memparam->sceKernelFlexibleMemorySize != nullptr) { accessMemoryManager()->flexibleMemory()->setTotalSize(*memparam->sceKernelFlexibleMemorySize); } } @@ -207,7 +208,7 @@ int main(int argc, char** argv) { pthread::attrInit(&attr); // set thread stack size if available - if (procParam->header.size < (8 + offsetof(ProcParam, sceUserMainThreadStackSize))) { + if (procParam->header.size > (8 + offsetof(ProcParam, sceUserMainThreadStackSize))) { if (procParam->sceUserMainThreadStackSize != 0 && *procParam->sceUserMainThreadStackSize != 0) pthread::attrSetstacksize(&attr, *procParam->sceUserMainThreadStackSize); } From e2298bd228d471780a5316d1772b954f22b28052 Mon Sep 17 00:00:00 2001 From: SysRay Date: Sun, 26 May 2024 15:24:52 +0200 Subject: [PATCH 4/5] fix query --- core/dmem/memoryManager.cpp | 15 +++++++-------- core/dmem/types/directmem.cpp | 24 +++++++++++------------ modules/libkernel/dmem.cpp | 36 +++++++++++++++++++++-------------- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/core/dmem/memoryManager.cpp b/core/dmem/memoryManager.cpp index 9354e96e..db53f637 100644 --- a/core/dmem/memoryManager.cpp +++ b/core/dmem/memoryManager.cpp @@ -91,21 +91,19 @@ int32_t MemoryManager::virtualQuery(uint64_t addr, SceKernelVirtualQueryInfo* in boost::unique_lock lock(m_mutexInt); auto itItem = m_mappings.lower_bound(addr); - if (itItem == m_mappings.end() || (itItem != m_mappings.begin() && itItem->first != addr)) --itItem; // Get the correct item - if (!(itItem->first <= addr && (itItem->first + itItem->second.size >= addr))) { - LOG_TRACE(L"Query Error: addr:0x%08llx", addr); - return getErr(ErrCode::_EACCES); - } + if (itItem == m_mappings.end() && addr > (itItem->first + itItem->second.size)) return getErr(ErrCode::_EACCES); // End reached + + if (itItem == m_mappings.end() || (itItem != m_mappings.begin() && itItem->first != addr)) --itItem; // Get the correct item int res = getErr(ErrCode::_EACCES); switch (itItem->second.type) { case MappingType::Direct: { - res = m_directMemory->virtualQuery(addr, info); + res = m_directMemory->virtualQuery(itItem->first, info); } break; case MappingType::Flexible: { - res = m_flexibleMemory->virtualQuery(addr, info); + res = m_flexibleMemory->virtualQuery(itItem->first, info); } break; case MappingType::Fixed: { } break; @@ -116,7 +114,8 @@ int32_t MemoryManager::virtualQuery(uint64_t addr, SceKernelVirtualQueryInfo* in } if (res == Ok) { - LOG_TRACE(L"Query OK: addr:0x%08llx - start:0x%08llx end:0x%08llx prot:%d type:%d", addr, info->start, info->end, info->protection, info->memoryType); + LOG_TRACE(L"Query OK: addr:0x%08llx - start:0x%08llx end:0x%08llx prot:%d type:%d", itItem->first, info->start, info->end, info->protection, + info->memoryType); } else { LOG_TRACE(L"Query Error: addr:0x%08llx", addr); } diff --git a/core/dmem/types/directmem.cpp b/core/dmem/types/directmem.cpp index 34a95b4f..f21c4968 100644 --- a/core/dmem/types/directmem.cpp +++ b/core/dmem/types/directmem.cpp @@ -222,7 +222,7 @@ int DirectMemory::alloc(size_t len, size_t alignment, int memoryType, uint64_t* m_allocSize += len; m_objects.emplace(std::make_pair( *outAddr, MemoryInfo {.addr = *outAddr, .size = len, .alignment = alignment, .memoryType = memoryType, .vmaAlloc = alloc, .vmaBlock = block})); - + m_parent->registerMapping(*outAddr, len, MappingType::Direct); LOG_DEBUG(L"-> Allocated: len:0x%08llx alignment:0x%08llx memorytype:%d -> 0x%08llx", len, alignment, memoryType, *outAddr); return Ok; @@ -349,6 +349,7 @@ int DirectMemory::map(uint64_t vaddr, off_t offset, size_t len, int prot, int fl info->allocAddr = ptr; info->state = MemoryState::Commited; + info->prot = prot; LOG_DEBUG(L"Commit| addr:0x%08llx len:0x%08llx prot:%d ->", info->addr, info->size, prot, ptr); } // - commit @@ -357,7 +358,6 @@ int DirectMemory::map(uint64_t vaddr, off_t offset, size_t len, int prot, int fl m_mappings.emplace( std::make_pair(*outAddr, MemoryMappingDirect {.addr = *outAddr, .heapAddr = info->addr, .size = len, .alignment = alignment, .vmaAlloc = alloc})); - m_parent->registerMapping(*outAddr, len, MappingType::Direct); m_usedSize += len; LOG_DEBUG(L"-> Map: start:0x%08llx(0x%x) len:0x%08llx alignment:0x%08llx prot:%d -> 0x%08llx", vaddr, offset, len, alignment, prot, *outAddr); @@ -397,6 +397,7 @@ int DirectMemory::reserve(uint64_t start, size_t len, size_t alignment, int flag m_objects.emplace( std::make_pair(*outAddr, MemoryInfo {.addr = *outAddr, .size = len, .alignment = alignment, .memoryType = 0, .state = MemoryState::Reserved})); + m_parent->registerMapping(*outAddr, len, MappingType::Direct); return Ok; } @@ -481,13 +482,12 @@ int32_t DirectMemory::virtualQuery(uint64_t addr, SceKernelVirtualQueryInfo* inf LOG_USE_MODULE(DirectMemory); boost::unique_lock lock(m_mutexInt); + if (m_objects.empty()) return getErr(ErrCode::_EACCES); auto itItem = m_objects.lower_bound(addr); - if (itItem == m_objects.end() || (itItem != m_objects.begin() && itItem->first != addr)) --itItem; // Get the correct item + if (itItem == m_objects.end() && addr > (itItem->first + itItem->second.size)) return getErr(ErrCode::_EACCES); // End reached - if (!(itItem->first <= addr && (itItem->first + itItem->second.size >= addr))) { - return getErr(ErrCode::_EACCES); - } + if (itItem == m_objects.end() || (itItem != m_objects.begin() && itItem->first != addr)) --itItem; // Get the correct item info->protection = itItem->second.prot; info->memoryType = itItem->second.memoryType; @@ -496,10 +496,10 @@ int32_t DirectMemory::virtualQuery(uint64_t addr, SceKernelVirtualQueryInfo* inf info->isPooledMemory = false; // info->isStack = false; // done by parent - auto itMapping = m_mappings.lower_bound(addr); - if (itMapping == m_mappings.end() || (itMapping != m_mappings.begin() && itMapping->first != addr)) --itMapping; // Get the correct item + auto itMapping = m_mappings.lower_bound(itItem->first); + if (itMapping == m_mappings.end() || (itMapping != m_mappings.begin() && itMapping->first != itItem->first)) --itMapping; // Get the correct item - if (!(itMapping->first <= addr && (itMapping->first + itMapping->second.size > addr))) { + if (!(itMapping->first <= itItem->first && (itMapping->first + itMapping->second.size > itItem->first))) { if (itItem->second.state == MemoryState::Reserved) { info->start = (void*)itItem->first; info->end = (void*)(itItem->first + itItem->second.size); @@ -512,7 +512,7 @@ int32_t DirectMemory::virtualQuery(uint64_t addr, SceKernelVirtualQueryInfo* inf info->start = (void*)itMapping->first; info->end = (void*)(itMapping->first + itMapping->second.size); - info->offset = itMapping->second.heapAddr - itMapping->first; + info->offset = 0; info->isCommitted = true; return Ok; @@ -526,8 +526,8 @@ int32_t DirectMemory::directQuery(uint64_t offset, SceKernelDirectMemoryQueryInf for (auto& item: m_objects) { auto off = item.second.addr - DIRECTMEM_START; if (offset >= off && offset < off + item.second.size) { - info->start = off; - info->end = off + item.second.size; + info->start = item.second.addr; + info->end = item.second.addr + item.second.size; info->memoryType = item.second.memoryType; diff --git a/modules/libkernel/dmem.cpp b/modules/libkernel/dmem.cpp index 74d36a74..583430fd 100644 --- a/modules/libkernel/dmem.cpp +++ b/modules/libkernel/dmem.cpp @@ -173,26 +173,34 @@ EXPORT SYSV_ABI int32_t sceKernelIsStack(void* addr, void** start, void** end) { EXPORT SYSV_ABI int32_t sceKernelVirtualQuery(uintptr_t addr, int flags, SceKernelVirtualQueryInfo* info, size_t infoSize) { if (info == nullptr || infoSize != sizeof(SceKernelVirtualQueryInfo)) return getErr(ErrCode::_EFAULT); - if (accessMemoryManager()->virtualQuery((uint64_t)addr, info) == Ok) return Ok; - LOG_USE_MODULE(dmem); + constexpr uint64_t DIRECTMEM_START = 0x100000000u; - uint64_t base = (uint64_t)addr; + if (addr >= DIRECTMEM_START) { + if (accessMemoryManager()->virtualQuery((uint64_t)addr, info) != Ok) { + LOG_TRACE(L"Query Error: addr:0x%08llx -> start:0x%08llx, end:0x%08llx, type:%d", addr, info->start, info->end, info->memoryType); + return getErr(ErrCode::_EACCES); + } + } else { + uint64_t base = (uint64_t)addr; - if ((uint64_t)addr < IMAGE_BASE) { - addr = IMAGE_BASE; - } + if ((uint64_t)addr < IMAGE_BASE) { + addr = IMAGE_BASE; + } - base = memory::queryAlloc(addr, (uintptr_t*)&info->start, (uintptr_t*)&info->end, &info->protection); - if (base <= 0) { - LOG_TRACE(L"Query Error: addr:0x%08llx -> start:0x%08llx, end:0x%08llx, type:%d", addr, info->start, info->end, info->memoryType); - return getErr(ErrCode::_EACCES); + base = memory::queryAlloc(addr, (uintptr_t*)&info->start, (uintptr_t*)&info->end, &info->protection); + if (base <= 0) { + if (accessMemoryManager()->virtualQuery((uint64_t)addr, info) != Ok) { + LOG_TRACE(L"Query Error: addr:0x%08llx -> start:0x%08llx, end:0x%08llx, type:%d", addr, info->start, info->end, info->memoryType); + return getErr(ErrCode::_EACCES); + } + } else { + info->isCommitted = true; + info->isFlexibleMemory = true; + info->offset = 0; + } } - info->isCommitted = true; - info->isFlexibleMemory = true; - info->offset = (int64_t)addr - (int64_t)info->start; - LOG_TRACE(L"Query OK: addr:0x%08llx -> start:0x%08llx end:0x%08llx prot:%d type:%d", addr, info->start, info->end, info->protection, info->memoryType); return Ok; } From 66314423ddb58361e426e717469459efa0daa12e Mon Sep 17 00:00:00 2001 From: SysRay Date: Sun, 26 May 2024 15:25:14 +0200 Subject: [PATCH 5/5] relocate only for spec. lib --- core/runtime/formats/IFormat.h | 2 +- core/runtime/formats/elf64.cpp | 22 ++++++++++++++++------ core/runtime/runtimeLinker.cpp | 8 ++++++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/core/runtime/formats/IFormat.h b/core/runtime/formats/IFormat.h index 115162a7..7c493a22 100644 --- a/core/runtime/formats/IFormat.h +++ b/core/runtime/formats/IFormat.h @@ -49,7 +49,7 @@ class IFormat: public Symbols::IResolve { virtual Symbols::SymbolInfo getSymbolInfo(uint64_t const relIndex) const = 0; - virtual void relocate(Program const* prog, uint64_t invalidMemoryAddr) = 0; + virtual void relocate(Program const* prog, uint64_t invalidMemoryAddr, std::string_view libName) = 0; virtual std::unordered_map getDebugStrings() const = 0; virtual std::string collectDebugInfos(std::unordered_map& debugStrings) const = 0; diff --git a/core/runtime/formats/elf64.cpp b/core/runtime/formats/elf64.cpp index a1b0fd47..61a87fff 100644 --- a/core/runtime/formats/elf64.cpp +++ b/core/runtime/formats/elf64.cpp @@ -500,7 +500,7 @@ class Parser_ELF64: public IFormat { Symbols::RelocationInfo getRelocationInfo(IRuntimeLinker const* linker, elf64::Elf64_Rela const* r, Program const* prog, elf64::SymbolMap const& symbolsMap) const; - void relocate(Program const* prog, uint64_t invalidMemoryAddr) final; + void relocate(Program const* prog, uint64_t invalidMemoryAddr, std::string_view libName) final; bool isShared() const { return (m_elfHeader->type == elf64::ET_DYNAMIC); } @@ -1420,7 +1420,7 @@ void Parser_ELF64::setupMissingRelocationHandler(Program* prog, void* relocateHa } } -void Parser_ELF64::relocate(Program const* prog, uint64_t invalidMemoryAddr) { +void Parser_ELF64::relocate(Program const* prog, uint64_t invalidMemoryAddr, std::string_view libName) { LOG_USE_MODULE(ELF64); LOG_INFO(L"relocate %s", prog->filename.c_str()); @@ -1431,12 +1431,22 @@ void Parser_ELF64::relocate(Program const* prog, uint64_t invalidMemoryAddr) { return ret; }; - auto relocateAll = [this, prog, invalidMemoryAddr, load](IRuntimeLinker& linker, elf64::Elf64_Rela const* records, uint64_t numBytes, - bool const isJmpRelaTable) { + auto relocateAll = [&](IRuntimeLinker& linker, elf64::Elf64_Rela const* records, uint64_t numBytes, bool const isJmpRelaTable) { uint32_t index = 0; for (auto const* r = records; reinterpret_cast(r) < reinterpret_cast(records) + numBytes; r++, index++) { - auto const ri = getRelocationInfo(&linker, r, prog, m_dynamicInfo->symbolsMap); - bool patched = false; + auto const ri = getRelocationInfo(&linker, r, prog, m_dynamicInfo->symbolsMap); + + if (!libName.empty()) { + auto idData = util::splitString(ri.name, '#'); + + if (idData.size() == 3) { + auto lib = getLibrary(m_dynamicInfo.get(), idData[1]); + if (lib->name != libName) continue; + } else + continue; + } + + bool patched = false; if (ri.resolved) { patched = patchReplace(ri.vaddr, ri.value); } else { diff --git a/core/runtime/runtimeLinker.cpp b/core/runtime/runtimeLinker.cpp index 49ed6a89..e76bfac4 100644 --- a/core/runtime/runtimeLinker.cpp +++ b/core/runtime/runtimeLinker.cpp @@ -569,9 +569,13 @@ int RuntimeLinker::loadStartModule(std::filesystem::path const& path, size_t arg // - imports // relocate + auto libName = pProgram->filename.stem().string(); for (auto& prog: m_programList) { - prog.second->relocate(prog.first.get(), m_invalidMemoryAddr); + if (prog.second->getImportedLibs().find(libName) == prog.second->getImportedLibs().end()) continue; + + prog.second->relocate(prog.first.get(), m_invalidMemoryAddr, libName); } + format->relocate(pProgram, m_invalidMemoryAddr, ""); uintptr_t const entryAddr = pProgram->entryOffAddr + pProgram->baseVaddr; LOG_INFO(L"-> Starting %s entry:0x%08llx tlsIndex:%u", pProgram->filename.c_str(), entryAddr, tlsIndex); @@ -840,7 +844,7 @@ uintptr_t RuntimeLinker::execute() { // Relocate all (Set Imported Symbols) m_invalidMemoryAddr = memory::alloc(INVALID_MEMORY, 4096, 0); for (auto& prog: m_programList) { - if (prog.first) prog.second->relocate(prog.first.get(), m_invalidMemoryAddr); + if (prog.first) prog.second->relocate(prog.first.get(), m_invalidMemoryAddr, ""); } setupTlsStaticBlock(); // relocate may init tls -> copy after relocate