mirror of
https://github.com/SysRay/psOff_public.git
synced 2024-10-07 03:43:54 +00:00
commit
6d58b63d47
@ -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);
|
||||
}
|
||||
|
@ -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<uint64_t, MemoryInfo> m_objects;
|
||||
std::map<uint64_t, MemoryMapping> m_mappings;
|
||||
std::map<uint64_t, MemoryInfo> m_objects;
|
||||
std::map<uint64_t, MemoryMappingDirect> m_mappings;
|
||||
|
||||
uint64_t m_allocSize = 0;
|
||||
uint64_t m_usedSize = 0;
|
||||
@ -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,15 +349,15 @@ 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
|
||||
|
||||
*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;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -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<uint64_t, std::string_view> getDebugStrings() const = 0;
|
||||
virtual std::string collectDebugInfos(std::unordered_map<uint64_t, std::string_view>& debugStrings) const = 0;
|
||||
|
@ -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<uint8_t const*>(r) < reinterpret_cast<uint8_t const*>(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 {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
@ -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
|
||||
|
9
main.cpp
9
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);
|
||||
}
|
||||
|
@ -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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -100,10 +100,17 @@ EXPORT SYSV_ABI void* _sceModuleParam() {
|
||||
return reinterpret_cast<void*>(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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user