Merge pull request #1 from wheremyfoodat/pthreadz

Pthreadz
This commit is contained in:
wheremyfoodat 2023-07-18 19:00:13 +03:00 committed by GitHub
commit dd46d270c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 893 additions and 91 deletions

7
.clang-format Normal file
View File

@ -0,0 +1,7 @@
BasedOnStyle: Google
IndentWidth: 4
ColumnLimit: 150
AccessModifierOffset: -2
TabWidth: 4
AllowShortEnumsOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true

50
.github/workflows/linux.yml vendored Normal file
View File

@ -0,0 +1,50 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Linux
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Install dev packages
run: |
sudo apt install libxext-dev doxygen libgl-dev
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel `nproc`
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.2
with:
name: shadps4-ubuntu64
# A file, directory or wildcard pattern that describes what to upload
path: |
${{github.workspace}}/build/shadps4
${{github.workspace}}/build/libSDL3.so.0.0.0

10
.gitmodules vendored
View File

@ -1,18 +1,28 @@
[submodule "third-party/imgui"] [submodule "third-party/imgui"]
path = third-party/imgui path = third-party/imgui
url = https://github.com/ocornut/imgui url = https://github.com/ocornut/imgui
shallow = true
[submodule "third-party/SDL"] [submodule "third-party/SDL"]
path = third-party/SDL path = third-party/SDL
url = https://github.com/libsdl-org/SDL url = https://github.com/libsdl-org/SDL
shallow = true
[submodule "third-party/fmt"] [submodule "third-party/fmt"]
path = third-party/fmt path = third-party/fmt
url = https://github.com/fmtlib/fmt.git url = https://github.com/fmtlib/fmt.git
shallow = true
[submodule "third-party/spdlog"] [submodule "third-party/spdlog"]
path = third-party/spdlog path = third-party/spdlog
url = https://github.com/gabime/spdlog url = https://github.com/gabime/spdlog
shallow = true
[submodule "third-party/magic_enum"] [submodule "third-party/magic_enum"]
path = third-party/magic_enum path = third-party/magic_enum
url = https://github.com/Neargye/magic_enum.git url = https://github.com/Neargye/magic_enum.git
shallow = true
[submodule "third-party/zydis"] [submodule "third-party/zydis"]
path = third-party/zydis path = third-party/zydis
url = https://github.com/zyantific/zydis.git url = https://github.com/zyantific/zydis.git
shallow = true
[submodule "third-party/winpthread"]
path = third-party/winpthread
url = https://github.com/shadps4/winpthread.git
branch = main

View File

@ -15,8 +15,8 @@ include_directories(third-party/sdl/)
include_directories(third-party/fmt/include) include_directories(third-party/fmt/include)
include_directories(third-party/magic_enum/include) include_directories(third-party/magic_enum/include)
include_directories(third-party/zydis/include/Zydis) include_directories(third-party/zydis/include/Zydis)
include_directories(third-party/winpthread/include)
add_subdirectory("third-party") add_subdirectory("third-party")
#=================== EXAMPLE =================== #=================== EXAMPLE ===================
add_executable(shadps4 add_executable(shadps4
@ -34,13 +34,15 @@ add_executable(shadps4
src/Core/Memory.h src/Core/Memory.h
src/Core/PS4/Linker.cpp src/Core/PS4/Linker.cpp
src/Core/PS4/Linker.h src/Core/PS4/Linker.h
"src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Util/StringUtil.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Lib/Timer.cpp" "src/Lib/Timer.h") "src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Util/StringUtil.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Lib/Timer.cpp" "src/Lib/Timer.h" "src/Core/PS4/HLE/LibKernel.cpp" "src/Core/PS4/HLE/LibKernel.h" "src/Core/PS4/HLE/LibSceVideoOut.cpp" "src/Core/PS4/HLE/LibSceVideoOut.h" "src/Core/PS4/HLE/LibSceGnmDriver.cpp" "src/Core/PS4/HLE/LibSceGnmDriver.h" "src/Core/PS4/HLE/Kernel/ThreadManagement.cpp" "src/Core/PS4/HLE/Kernel/ThreadManagement.h" "src/Core/PS4/HLE/ErrorCodes.h")
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
target_link_libraries(shadps4 PUBLIC fmt spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY}) target_link_libraries(shadps4 PUBLIC fmt spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY})
add_custom_command(TARGET shadps4 POST_BUILD add_custom_command(TARGET shadps4 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:SDL3-shared> $<TARGET_FILE:SDL3-shared>
$<TARGET_FILE_DIR:shadps4>) $<TARGET_FILE_DIR:shadps4>)
add_custom_command(TARGET shadps4 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PROJECT_SOURCE_DIR}/third-party/winpthread/bin/libwinpthread-1.dll" $<TARGET_FILE_DIR:shadps4>)

View File

@ -45,7 +45,7 @@ make -j$(nproc)
|Platform|Build status| |Platform|Build status|
|--------|------------| |--------|------------|
|Windows build|[![Windows](https://github.com/georgemoralis/shadPS4/actions/workflows/windows.yml/badge.svg)](https://github.com/georgemoralis/shadPS4/actions/workflows/windows.yml) |Windows build|[![Windows](https://github.com/georgemoralis/shadPS4/actions/workflows/windows.yml/badge.svg)](https://github.com/georgemoralis/shadPS4/actions/workflows/windows.yml)
|Linux build| TODO |Linux build|[![Linux](https://github.com/georgemoralis/shadPS4/actions/workflows/linux.yml/badge.svg)](https://github.com/georgemoralis/shadPS4/actions/workflows/linux.yml)
To discuss this emulator please join our Discord server: [![Discord](https://img.shields.io/discord/1080089157554155590)](https://discord.gg/MyZRaBngxA) To discuss this emulator please join our Discord server: [![Discord](https://img.shields.io/discord/1080089157554155590)](https://discord.gg/MyZRaBngxA)

View File

@ -42,6 +42,17 @@ namespace Memory
return PAGE_NOACCESS; return PAGE_NOACCESS;
} }
} }
static MemoryMode convertMemoryMode(u32 mode) {
switch (mode) {
case PAGE_NOACCESS: return MemoryMode::NoAccess;
case PAGE_READONLY: return MemoryMode::Read;
case PAGE_READWRITE: return MemoryMode::ReadWrite;
case PAGE_EXECUTE: return MemoryMode::Execute;
case PAGE_EXECUTE_READ: return MemoryMode::ExecuteRead;
case PAGE_EXECUTE_READWRITE: return MemoryMode::ExecuteReadWrite;
default: return MemoryMode::NoAccess;
}
}
u64 memory_alloc(u64 address, u64 size, MemoryMode mode) u64 memory_alloc(u64 address, u64 size, MemoryMode mode)
{ {
@ -71,5 +82,46 @@ namespace Memory
#endif #endif
return ptr; return ptr;
} }
bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode) {
DWORD old_protect = 0;
if (VirtualProtect(reinterpret_cast<LPVOID>(static_cast<uintptr_t>(address)), size, convertMemoryMode(mode), &old_protect) == 0) {
auto err = static_cast<u32>(GetLastError());
LOG_ERROR_IF(true, "VirtualProtect() failed: 0x{:X}\n", err);
return false;
}
if (old_mode != nullptr) {
*old_mode = convertMemoryMode(old_protect);
}
return true;
}
bool memory_flush(u64 address, u64 size) {
if (::FlushInstructionCache(GetCurrentProcess(), reinterpret_cast<LPVOID>(static_cast<uintptr_t>(address)), size) == 0) {
auto err = static_cast<u32>(GetLastError());
LOG_ERROR_IF(true, "FlushInstructionCache() failed: 0x{:X}\n", err);
return false;
}
return true;
}
bool memory_patch(u64 vaddr, u64 value) {
MemoryMode old_mode{};
memory_protect(vaddr, 8, MemoryMode::ReadWrite, &old_mode);
auto* ptr = reinterpret_cast<uint64_t*>(vaddr);
bool ret = (*ptr != value);
*ptr = value;
memory_protect(vaddr, 8, old_mode, nullptr);
//if mode is executable flush it so insure that cpu finds it
if ((old_mode == MemoryMode::Execute || old_mode == MemoryMode::ExecuteRead || old_mode == MemoryMode::ExecuteWrite ||
old_mode == MemoryMode::ExecuteReadWrite)) {
memory_flush(vaddr, 8);
}
return ret;
}
} }
} }

View File

@ -20,5 +20,8 @@ namespace Memory
namespace VirtualMemory { namespace VirtualMemory {
u64 memory_alloc(u64 address, u64 size, MemoryMode mode); u64 memory_alloc(u64 address, u64 size, MemoryMode mode);
bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode);
bool memory_flush(u64 address, u64 size);
bool memory_patch(u64 vaddr, u64 value);
} }
} }

View File

@ -0,0 +1,5 @@
#pragma once
constexpr int SCE_OK = 0;
constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000c;//Insufficient memory
constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016;//null or invalid states

View File

@ -0,0 +1,125 @@
#include "ThreadManagement.h"
#include "../ErrorCodes.h"
namespace HLE::Libs::LibKernel::ThreadManagement
{
thread_local PthreadInternal* g_pthread_self = nullptr;
PThreadCxt* g_pthread_cxt = nullptr;
int scePthreadAttrInit(ScePthreadAttr* attr) {
*attr = new PthreadAttrInternal{};
int result = pthread_attr_init(&(*attr)->p);
(*attr)->affinity = 0x7f;
(*attr)->guard_size = 0x1000;
SceKernelSchedParam param{};
param.sched_priority = 700;
result = (result == 0 ? scePthreadAttrSetinheritsched(attr, PTHREAD_INHERIT_SCHED) : result);
result = (result == 0 ? scePthreadAttrSetschedparam(attr, &param) : result);
result = (result == 0 ? scePthreadAttrSetschedpolicy(attr, SCHED_OTHER) : result);
result = (result == 0 ? scePthreadAttrSetdetachstate(attr, PTHREAD_CREATE_JOINABLE) : result);
switch (result) {
case 0: return SCE_OK;
case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM;
default: return SCE_KERNEL_ERROR_EINVAL;
}
}
int scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachstate) {
if (attr == nullptr || *attr == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
int pstate = PTHREAD_CREATE_JOINABLE;
switch (detachstate) {
case 0: pstate = PTHREAD_CREATE_JOINABLE; break;
case 1: pstate = PTHREAD_CREATE_DETACHED; break;
default:
__debugbreak(); //unknown state
}
int result = pthread_attr_setdetachstate(&(*attr)->p, pstate);
(*attr)->detached = (pstate == PTHREAD_CREATE_DETACHED);
if (result == 0) {
return SCE_OK;
}
return SCE_KERNEL_ERROR_EINVAL;
}
int scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched) {
if (attr == nullptr || *attr == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
int pinherit_sched = PTHREAD_INHERIT_SCHED;
switch (inheritSched) {
case 0: pinherit_sched = PTHREAD_EXPLICIT_SCHED; break;
case 4: pinherit_sched = PTHREAD_INHERIT_SCHED; break;
default: __debugbreak(); // unknown inheritSched
}
int result = pthread_attr_setinheritsched(&(*attr)->p, pinherit_sched);
if (result == 0) {
return SCE_OK;
}
return SCE_KERNEL_ERROR_EINVAL;
}
int scePthreadAttrSetschedparam(ScePthreadAttr* attr, const SceKernelSchedParam* param) {
if (param == nullptr || attr == nullptr || *attr == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
SceKernelSchedParam pparam{};
if (param->sched_priority <= 478) {
pparam.sched_priority = +2;
} else if (param->sched_priority >= 733) {
pparam.sched_priority = -2;
} else {
pparam.sched_priority = 0;
}
int result = pthread_attr_setschedparam(&(*attr)->p, &pparam);
if (result == 0) {
return SCE_OK;
}
return SCE_KERNEL_ERROR_EINVAL;
}
int scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy) {
if (attr == nullptr || *attr == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
if (policy!= SCHED_OTHER)
{
__debugbreak();//invest if policy is other and if winpthreadlibrary support it
}
(*attr)->policy = policy;
int result = pthread_attr_setschedpolicy(&(*attr)->p, policy);
if (result == 0) {
return SCE_OK;
}
return SCE_KERNEL_ERROR_EINVAL;
}
};

View File

@ -0,0 +1,37 @@
#pragma once
#include <pthread.h>
#include <sched.h>
#include "../../../../types.h"
extern "C" {
struct sched_param;
}
namespace HLE::Libs::LibKernel::ThreadManagement {
struct PthreadAttrInternal;
using SceKernelSchedParam = struct sched_param;
using ScePthreadAttr = PthreadAttrInternal*;
struct PthreadInternal {
pthread_t p;
};
struct PthreadAttrInternal {
u64 affinity;
size_t guard_size;
int policy;
bool detached;
pthread_attr_t p;
};
class PThreadCxt {};
//HLE FUNCTIONS
int scePthreadAttrInit(ScePthreadAttr* attr);
int scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachstate);
int scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched);
int scePthreadAttrSetschedparam(ScePthreadAttr* attr, const SceKernelSchedParam* param);
int scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy);
} // namespace HLE::Libs::LibKernel::ThreadManagement

View File

@ -1,8 +1,11 @@
#include "LibC.h" #include "LibC.h"
#include "Libs.h"
#include "../Loader/Elf.h" #include "../Loader/Elf.h"
namespace HLE::Libs::LibC { namespace HLE::Libs::LibC {
static u32 g_need_sceLibc = 1;
static void init_env() //every game/demo should probably static void init_env() //every game/demo should probably
{ {
for(;;) { for(;;) {
@ -11,18 +14,46 @@ namespace HLE::Libs::LibC {
//__debugbreak();//if we reach here it will be a great progress :D //__debugbreak();//if we reach here it will be a great progress :D
} }
void LibC_RegisterFunc(SymbolsResolver* sym) int __cxa_guard_acquire(u64* guard_object)
{ { return 0;
//TODO this will be convert to macro probably once we decide how will it work and what's the best
SymbolRes sr {};
sr.name = "bzQExy189ZI";
sr.library = "libc";
sr.library_version = 1;
sr.module = "libc";
sr.module_version_major = 1;
sr.module_version_minor = 1;
sr.type = STT_FUN;
auto func = reinterpret_cast<u64>(init_env);
sym->AddSymbol(sr, func);
} }
int __cxa_guard_release(u64* guard_object)
{ return 0;
}
int memcmp(const void* s1, const void* s2, size_t n) {
return ::memcmp(s1, s2, n);
}
void* memcpy(void* dest, const void* src, size_t n) {
return ::memcpy(dest, src, n);
}
static void catchReturnFromMain(int status)
{
}
static void exit(int code)
{
}
static int atexit(void (*func)())
{ return 0;
}
void LibC_Register(SymbolsResolver* sym)
{
LIB_FUNCTION("bzQExy189ZI", "libc", 1, "libc", 1, 1, init_env);
LIB_FUNCTION("3GPpjQdAMTw", "libc", 1, "libc", 1, 1, __cxa_guard_acquire);
LIB_FUNCTION("9rAeANT2tyE", "libc", 1, "libc", 1, 1, __cxa_guard_release);
LIB_FUNCTION("DfivPArhucg", "libc", 1, "libc", 1, 1, memcmp);
LIB_FUNCTION("Q3VBxCXhUHs", "libc", 1, "libc", 1, 1, memcpy);
LIB_FUNCTION("XKRegsFpEpk", "libc", 1, "libc", 1, 1, catchReturnFromMain);
LIB_FUNCTION("uMei1W9uyNo", "libc", 1, "libc", 1, 1, exit);
LIB_FUNCTION("8G2LB+A3rzg", "libc", 1, "libc", 1, 1, atexit);
LIB_OBJ("P330P3dFF68", "libc", 1, "libc", 1, 1, &HLE::Libs::LibC::g_need_sceLibc);
}
}; };

View File

@ -3,8 +3,12 @@
namespace HLE::Libs::LibC { namespace HLE::Libs::LibC {
void LibC_RegisterFunc(SymbolsResolver* sym); void LibC_Register(SymbolsResolver* sym);
//functions //functions
static void init_env(); static void init_env();
static void exit(int code);
static void catchReturnFromMain(int status);
int __cxa_guard_acquire(u64* guard_object);
int memcmp(const void* s1, const void* s2, size_t n);
void* memcpy(void* dest, const void* src, size_t n);
}; };

View File

@ -0,0 +1,46 @@
#include "../Loader/Elf.h"
#include "LibKernel.h"
#include "Libs.h"
namespace HLE::Libs::LibKernel {
static u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; //dummy return
int sceKernelAllocateDirectMemory(off_t searchStart, off_t searchEnd, size_t len, size_t alignment, int memoryType, off_t* physAddrOut) { return 0;//OK
}
size_t sceKernelGetDirectMemorySize() { return 0;
}
int32_t sceKernelMapDirectMemory(void** addr, size_t len, int prot, int flags, off_t directMemoryStart, size_t alignment) { return 0;
}
int32_t sceKernelReleaseDirectMemory(off_t start, size_t len) { return 0;
}
int sceKernelCreateEqueue(/* SceKernelEqueue* eq*/int eq,const char* name)
{ return 0;
}
int sceKernelWaitEqueue(/*SceKernelEqueue eq, SceKernelEvent* ev,*/ int num, int* out /*, SceKernelUseconds* timo*/) { return 0;
}
int sceKernelIsNeoMode()
{ return 0;
}
static void stack_chk_fail() {
}
void LibKernel_Register(SymbolsResolver* sym) {
//obj
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &HLE::Libs::LibKernel::g_stack_chk_guard);
//memory
LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateDirectMemory);
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
LIB_FUNCTION("MBuItvba6z8", "libkernel", 1, "libkernel", 1, 1, sceKernelReleaseDirectMemory);
//equeue
LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEqueue);
LIB_FUNCTION("fzyMKs9kim0", "libkernel", 1, "libkernel", 1, 1, sceKernelWaitEqueue);
//misc
LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, sceKernelIsNeoMode);
LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail);
}
};

View File

@ -0,0 +1,14 @@
#include "../Loader/SymbolsResolver.h"
namespace HLE::Libs::LibKernel {
void LibKernel_Register(SymbolsResolver* sym);
// functions
int sceKernelAllocateDirectMemory(off_t searchStart, off_t searchEnd, size_t len, size_t alignment, int memoryType, off_t* physAddrOut);
size_t sceKernelGetDirectMemorySize();
int sceKernelCreateEqueue(/* SceKernelEqueue* eq*/ int eq, const char* name);
int32_t sceKernelMapDirectMemory(void** addr, size_t len, int prot, int flags, off_t directMemoryStart, size_t alignment);
int32_t sceKernelReleaseDirectMemory(off_t start, size_t len);
int sceKernelIsNeoMode();
int sceKernelWaitEqueue(/*SceKernelEqueue eq, SceKernelEvent* ev,*/ int num, int* out /*, SceKernelUseconds* timo*/);
}; // namespace HLE::Libs::LibKernel

View File

@ -0,0 +1,160 @@
#include "LibSceGnmDriver.h"
#include "Libs.h"
#include "../Loader/Elf.h"
namespace HLE::Libs::LibSceGnmDriver {
int sceGnmAddEqEvent(/* SceKernelEqueue eq, EqEventType id,*/ void* udata)
{ return 0;
}
bool sceGnmAreSubmitsAllowed()
{
return true;
}
int /* WorkloadStatus*/ sceGnmBeginWorkload(uint64_t* workload /*, WorkloadStream stream*/)
{
return 0;
}
int /* WorkloadStatus*/ sceGnmCreateWorkloadStream(/* WorkloadStream* workloadStream,*/ const char* name)
{
return 0;
}
void sceGnmDebugHardwareStatus(/* HardwareStatus flag*/) {
}
void sceGnmSetGsRingSizes(/* GsRingSizeSetup esgsRingSize, GsRingSizeSetup gsvsRingSize*/)
{
}
int32_t sceGnmSetWaveLimitMultipliers(uint16_t targetPipeMask, uint8_t gfxRatio, const uint8_t (*pipeRatios)[7])
{ return 0;
}
int /*MipStatsError*/ sceGnmSetupMipStatsReport(void* outputBuffer, uint32_t sizeInBytes, uint8_t intervalsBetweenReports,
uint8_t numReportsBeforeReset /*, MipStatsResetForce mipStatsResetForce*/)
{
return 0;
}
int sceGnmSubmitCommandBuffers(uint32_t count, void* dcb_gpu_addrs[], const uint32_t* dcb_sizes_in_bytes, void* ccb_gpu_addrs[],
const uint32_t* ccb_sizes_in_bytes)
{
return 0;
}
int sceGnmSubmitAndFlipCommandBuffers(uint32_t count, void* dcb_gpu_addrs[], const uint32_t* dcb_sizes_in_bytes,
void* ccb_gpu_addrs[], const uint32_t* ccb_sizes_in_bytes, int handle, int index,
int flip_mode, int64_t flip_arg)
{
return 0;
}
void sceGnmDingDong(u32 ring_id, u32 offset_dw)
{
}
bool sceRazorIsLoaded()
{ return true;// hmm???
}
int sceGnmDeleteEqEvent(/* SceKernelEqueue eq, EqEventType id*/)
{ return 0;
}
int32_t sceGnmSubmitDone()
{ return 0;
}
int /* MipStatsError*/ sceGnmDisableMipStatsReport()
{ return 0;
}
int sceGnmSubmitAndFlipCommandBuffersForWorkload()
{ return 0;
}
int sceGnmSubmitCommandBuffersForWorkload()
{ return 0;
}
int /* WorkloadStatus*/ sceGnmDestroyWorkloadStream(/*WorkloadStream workloadStream*/)
{ return 0;
}
void sceGnmDingDongForWorkload()
{
}
void sceGnmDriverCaptureInProgress() {}
void sceGnmUnmapComputeQueue(){}
void sceGnmDriverTraceInProgress(){}
void sceGnmDriverTriggerCapture(){}
void sceGnmEndWorkload(){}
void sceGnmFlushGarlic(){}
void sceGnmGetEqEventType(){}
void sceGnmGetEqTimeStamp(){}
void sceGnmGetGpuBlockStatus(){}
void sceGnmGetGpuInfoStatus(){}
void sceGnmGetLastWaitedAddress(){}
void sceGnmGetNumTcaUnits(){}
void sceGnmGetOffChipTessellationBufferSize(){}
void sceGnmGetPhysicalCounterFromVirtualized(){}
void sceGnmGetProtectionFaultTimeStamp(){}
void sceGnmGetShaderProgramBaseAddress(){}
void sceGnmGetShaderStatus(){}
void sceGnmGetTheTessellationFactorRingBufferBaseAddress(){}
void sceGnmIsUserPaEnabled(){}
void sceGnmLogicalCuIndexToPhysicalCuIndex(){}
void sceGnmLogicalCuMaskToPhysicalCuMask(){}
void sceGnmMapComputeQueue(){}
void sceGnmMapComputeQueueWithPriority(){}
void sceRazorCaptureImmediate(){}
void sceGnmRequestFlipAndSubmitDone(){}
void sceGnmRequestFlipAndSubmitDoneForWorkload(){}
void sceGnmRequestMipStatsReportAndReset(){}
void LibSceGnmDriver_Register(SymbolsResolver* sym)
{
LIB_FUNCTION("b0xyllnVY-I", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAddEqEvent);
LIB_FUNCTION("b08AgtPlHPg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAreSubmitsAllowed);
LIB_FUNCTION("ihxrbsoSKWc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmBeginWorkload);
LIB_FUNCTION("5udAm+6boVg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmCreateWorkloadStream);
LIB_FUNCTION("qpGITzPE+Zc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDebugHardwareStatus);
LIB_FUNCTION("jtkqXpAOY6w", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSetGsRingSizes);
LIB_FUNCTION("XiyzNZ9J4nQ", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSetWaveLimitMultipliers);
LIB_FUNCTION("+xuDhxlWRPg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSetupMipStatsReport);
LIB_FUNCTION("zwY0YV91TTI", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSubmitCommandBuffers);
LIB_FUNCTION("xbxNatawohc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSubmitAndFlipCommandBuffers);
LIB_FUNCTION("Ga6r7H6Y0RI", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSubmitAndFlipCommandBuffersForWorkload);
LIB_FUNCTION("f33OrruQYbM", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceRazorIsLoaded);
LIB_FUNCTION("jRcI8VcgTz4", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSubmitCommandBuffersForWorkload);
LIB_FUNCTION("PVT+fuoS9gU", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDeleteEqEvent);
LIB_FUNCTION("yvZ73uQUqrk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSubmitDone);
LIB_FUNCTION("UtObDRQiGbs", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDestroyWorkloadStream);
LIB_FUNCTION("bX5IbRvECXk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDingDong);
LIB_FUNCTION("byXlqupd8cE", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDingDongForWorkload);
LIB_FUNCTION("HHo1BAljZO8", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDisableMipStatsReport);
LIB_FUNCTION("TLV4mswiZ4A", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDriverCaptureInProgress);
LIB_FUNCTION("ArSg-TGinhk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmUnmapComputeQueue);
LIB_FUNCTION("R6z1xM3pW-w", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDriverTraceInProgress);
LIB_FUNCTION("d88anrgNoKY", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDriverTriggerCapture);
LIB_FUNCTION("Fa3x75OOLRA", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmEndWorkload);
LIB_FUNCTION("iBt3Oe00Kvc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmFlushGarlic);
LIB_FUNCTION("UoYY0DWMC0U", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetEqEventType);
LIB_FUNCTION("H7-fgvEutM0", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetEqTimeStamp);
LIB_FUNCTION("oL4hGI1PMpw", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetGpuBlockStatus);
LIB_FUNCTION("tZCSL5ulnB4", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetGpuInfoStatus);
LIB_FUNCTION("iFirFzgYsvw", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetLastWaitedAddress);
LIB_FUNCTION("KnldROUkWJY", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetNumTcaUnits);
LIB_FUNCTION("FFVZcCu3zWU", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetOffChipTessellationBufferSize);
LIB_FUNCTION("dewXw5roLs0", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetPhysicalCounterFromVirtualized);
LIB_FUNCTION("fzJdEihTFV4", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetProtectionFaultTimeStamp);
LIB_FUNCTION("nEyFbYUloIM", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetShaderProgramBaseAddress);
LIB_FUNCTION("k7iGTvDQPLQ", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetShaderStatus);
LIB_FUNCTION("ln33zjBrfjk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmGetTheTessellationFactorRingBufferBaseAddress);
LIB_FUNCTION("jg33rEKLfVs", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmIsUserPaEnabled);
LIB_FUNCTION("26PM5Mzl8zc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmLogicalCuIndexToPhysicalCuIndex);
LIB_FUNCTION("RU74kek-N0c", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmLogicalCuMaskToPhysicalCuMask);
LIB_FUNCTION("29oKvKXzEZo", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmMapComputeQueue);
LIB_FUNCTION("A+uGq+3KFtQ", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmMapComputeQueueWithPriority);
LIB_FUNCTION("u9YKpRRHe-M", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceRazorCaptureImmediate);
LIB_FUNCTION("gObODli-OH8", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmRequestFlipAndSubmitDone);
LIB_FUNCTION("6YRHhh5mHCs", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmRequestFlipAndSubmitDoneForWorkload);
LIB_FUNCTION("f85orjx7qts", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmRequestMipStatsReportAndReset);
}
};

View File

@ -0,0 +1,58 @@
#pragma once
#include "../Loader/SymbolsResolver.h"
namespace HLE::Libs::LibSceGnmDriver {
void LibSceGnmDriver_Register(SymbolsResolver* sym);
//functions
int sceGnmAddEqEvent(/* SceKernelEqueue eq, EqEventType id,*/ void* udata);
bool sceGnmAreSubmitsAllowed();
int /* WorkloadStatus*/ sceGnmBeginWorkload(uint64_t* workload /*, WorkloadStream stream*/);
int /* WorkloadStatus*/ sceGnmCreateWorkloadStream(/* WorkloadStream* workloadStream,*/ const char* name);
void sceGnmDebugHardwareStatus(/* HardwareStatus flag*/);
void sceGnmSetGsRingSizes(/* GsRingSizeSetup esgsRingSize, GsRingSizeSetup gsvsRingSize*/);
int32_t sceGnmSetWaveLimitMultipliers(uint16_t targetPipeMask, uint8_t gfxRatio, const uint8_t (*pipeRatios)[7]);
int /*MipStatsError*/ sceGnmSetupMipStatsReport(void* outputBuffer, uint32_t sizeInBytes, uint8_t intervalsBetweenReports,
uint8_t numReportsBeforeReset /*, MipStatsResetForce mipStatsResetForce*/);
int sceGnmSubmitCommandBuffers(uint32_t count, void* dcb_gpu_addrs[], const uint32_t* dcb_sizes_in_bytes, void* ccb_gpu_addrs[],
const uint32_t* ccb_sizes_in_bytes);
int sceGnmSubmitAndFlipCommandBuffers(uint32_t count, void* dcb_gpu_addrs[], const uint32_t* dcb_sizes_in_bytes, void* ccb_gpu_addrs[],
const uint32_t* ccb_sizes_in_bytes, int handle, int index, int flip_mode, int64_t flip_arg);
void sceGnmDingDong(u32 ring_id, u32 offset_dw);
bool sceRazorIsLoaded();
int sceGnmDeleteEqEvent(/* SceKernelEqueue eq, EqEventType id*/);
int32_t sceGnmSubmitDone();
int /* MipStatsError*/ sceGnmDisableMipStatsReport();
int sceGnmSubmitAndFlipCommandBuffersForWorkload();
int sceGnmSubmitCommandBuffersForWorkload();
int /* WorkloadStatus*/ sceGnmDestroyWorkloadStream(/*WorkloadStream workloadStream*/);
void sceGnmDingDongForWorkload();
void sceGnmDriverCaptureInProgress();
void sceGnmUnmapComputeQueue();
void sceGnmDriverTraceInProgress();
void sceGnmDriverTriggerCapture();
void sceGnmEndWorkload();
void sceGnmFlushGarlic();
void sceGnmGetEqEventType();
void sceGnmGetEqTimeStamp();
void sceGnmGetGpuBlockStatus();
void sceGnmGetGpuInfoStatus();
void sceGnmGetLastWaitedAddress();
void sceGnmGetNumTcaUnits();
void sceGnmGetOffChipTessellationBufferSize();
void sceGnmGetPhysicalCounterFromVirtualized();
void sceGnmGetProtectionFaultTimeStamp();
void sceGnmGetShaderProgramBaseAddress();
void sceGnmGetShaderStatus();
void sceGnmGetTheTessellationFactorRingBufferBaseAddress();
void sceGnmIsUserPaEnabled();
void sceGnmLogicalCuIndexToPhysicalCuIndex();
void sceGnmLogicalCuMaskToPhysicalCuMask();
void sceGnmMapComputeQueue();
void sceGnmMapComputeQueueWithPriority();
void sceRazorCaptureImmediate();
void sceGnmRequestFlipAndSubmitDone();
void sceGnmRequestFlipAndSubmitDoneForWorkload();
void sceGnmRequestMipStatsReportAndReset();
}; // namespace HLE::Libs::LibSceGnmDriver

View File

@ -0,0 +1,49 @@
#include "LibSceVideoOut.h"
#include "Libs.h"
#include "../Loader/Elf.h"
namespace HLE::Libs::LibSceVideoOut {
int32_t sceVideoOutGetFlipStatus(int32_t handle /*, SceVideoOutFlipStatus* status*/){
return 0;
}
int32_t sceVideoOutSubmitFlip(int32_t handle, int32_t bufferIndex, int32_t flipMode,int64_t flipArg){
return 0;
}
int32_t sceVideoOutRegisterBuffers(int32_t handle, int32_t startIndex, void* const* addresses, int32_t bufferNum /*,
const SceVideoOutBufferAttribute* attribute*/) {
return 0;
}
int32_t sceVideoOutAddFlipEvent(/*SceKernelEqueue eq,*/ int32_t handle, void* udata) {
return 0;
}
int32_t sceVideoOutSetFlipRate(int32_t handle, int32_t rate) {
return 0;
}
void sceVideoOutSetBufferAttribute(/* SceVideoOutBufferAttribute* attribute,*/ uint32_t pixelFormat, uint32_t tilingMode, uint32_t aspectRatio,
uint32_t width, uint32_t height, uint32_t pitchInPixel)
{
}
int32_t sceVideoOutGetResolutionStatus(int32_t handle /*, SceVideoOutResolutionStatus* status*/)
{ return 0;
}
int32_t sceVideoOutOpen(/* SceUserServiceUserId userId,*/ int32_t busType, int32_t index, const void* param) { return 0;
}
int32_t sceVideoOutIsFlipPending(int32_t handle) { return 0;
}
void LibSceVideoOut_Register(SymbolsResolver* sym)
{
LIB_FUNCTION("SbU3dwp80lQ", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetFlipStatus);
LIB_FUNCTION("U46NwOiJpys", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutSubmitFlip);
LIB_FUNCTION("w3BY+tAEiQY", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutRegisterBuffers);
LIB_FUNCTION("HXzjK9yI30k", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutAddFlipEvent);
LIB_FUNCTION("CBiu4mCE1DA", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutSetFlipRate);
LIB_FUNCTION("i6-sR91Wt-4", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutSetBufferAttribute);
LIB_FUNCTION("6kPnj51T62Y", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetResolutionStatus);
LIB_FUNCTION("Up36PTk687E", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutOpen);
LIB_FUNCTION("zgXifHT9ErY", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutIsFlipPending);
}
};

View File

@ -0,0 +1,18 @@
#pragma once
#include "../Loader/SymbolsResolver.h"
namespace HLE::Libs::LibSceVideoOut {
void LibSceVideoOut_Register(SymbolsResolver* sym);
//functions
int32_t sceVideoOutGetFlipStatus(int32_t handle /*, SceVideoOutFlipStatus* status*/);
int32_t sceVideoOutSubmitFlip(int32_t handle, int32_t bufferIndex, int32_t flipMode, int64_t flipArg);
int32_t sceVideoOutRegisterBuffers(int32_t handle, int32_t startIndex, void* const* addresses, int32_t bufferNum /*,const SceVideoOutBufferAttribute* attribute*/);
int32_t sceVideoOutAddFlipEvent(/*SceKernelEqueue eq,*/ int32_t handle, void* udata);
int32_t sceVideoOutSetFlipRate(int32_t handle, int32_t rate);
void sceVideoOutSetBufferAttribute(/* SceVideoOutBufferAttribute* attribute,*/ uint32_t pixelFormat, uint32_t tilingMode, uint32_t aspectRatio,
uint32_t width, uint32_t height, uint32_t pitchInPixel);
int32_t sceVideoOutGetResolutionStatus(int32_t handle /*, SceVideoOutResolutionStatus* status*/);
int32_t sceVideoOutOpen(/* SceUserServiceUserId userId,*/ int32_t busType, int32_t index, const void* param);
int32_t sceVideoOutIsFlipPending(int32_t handle);
}; // namespace HLE::Libs::LibSceVideoOut

View File

@ -1,10 +1,16 @@
#include "Libs.h" #include "Libs.h"
#include "LibC.h" #include "LibC.h"
#include "LibKernel.h"
#include "LibSceVideoOut.h"
#include "LibSceGnmDriver.h"
namespace HLE::Libs { namespace HLE::Libs {
void Init_HLE_Libs(SymbolsResolver *sym) void Init_HLE_Libs(SymbolsResolver *sym)
{ {
LibC::LibC_RegisterFunc(sym); LibC::LibC_Register(sym);
LibKernel::LibKernel_Register(sym);
LibSceVideoOut::LibSceVideoOut_Register(sym);
LibSceGnmDriver::LibSceGnmDriver_Register(sym);
} }
} }

View File

@ -1,6 +1,34 @@
#pragma once #pragma once
#include "../Loader/SymbolsResolver.h" #include "../Loader/SymbolsResolver.h"
#define LIB_FUNCTION(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \
{\
SymbolRes sr{}; \
sr.name = nid; \
sr.library = lib; \
sr.library_version = libversion;\
sr.module = mod;\
sr.module_version_major = moduleVersionMajor;\
sr.module_version_minor = moduleVersionMinor;\
sr.type = STT_FUN;\
auto func = reinterpret_cast<u64>(function);\
sym->AddSymbol(sr, func);\
}
#define LIB_OBJ(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \
{ \
SymbolRes sr{}; \
sr.name = nid; \
sr.library = lib; \
sr.library_version = libversion; \
sr.module = mod; \
sr.module_version_major = moduleVersionMajor; \
sr.module_version_minor = moduleVersionMinor; \
sr.type = STT_OBJECT; \
auto func = reinterpret_cast<u64>(function); \
sym->AddSymbol(sr, func); \
}
namespace HLE::Libs { namespace HLE::Libs {
void Init_HLE_Libs(SymbolsResolver* sym); void Init_HLE_Libs(SymbolsResolver* sym);
} }

View File

@ -70,6 +70,7 @@ static std::string encodeId(u64 nVal)
Module* Linker::LoadModule(const std::string& elf_name) Module* Linker::LoadModule(const std::string& elf_name)
{ {
auto* m = new Module; auto* m = new Module;
m->linker = this;
m->elf = new Elf; m->elf = new Elf;
m->elf->Open(elf_name);//load elf m->elf->Open(elf_name);//load elf
@ -497,67 +498,78 @@ void Linker::LoadSymbols(Module* m)
} }
} }
} }
static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel) static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel) {
{ auto type = rel->GetType();
auto type = rel->GetType(); auto symbol = rel->GetSymbol();
auto symbol = rel->GetSymbol(); auto addend = rel->rel_addend;
auto addend = rel->rel_addend; auto* symbolsTlb = m->dynamic_info->symbol_table;
auto* symbolsTlb = m->dynamic_info->symbol_table; auto* namesTlb = m->dynamic_info->str_table;
auto* namesTlb = m->dynamic_info->str_table;
u64 rel_value = 0; u64 rel_value = 0;
u64 rel_base_virtual_addr = m->base_virtual_addr; u64 rel_base_virtual_addr = m->base_virtual_addr;
u64 rel_virtual_addr = m->base_virtual_addr + rel->rel_offset; u64 rel_virtual_addr = m->base_virtual_addr + rel->rel_offset;
bool rel_isResolved = false; bool rel_isResolved = false;
u08 rel_sym_type = 0; u08 rel_sym_type = 0;
std::string rel_name; std::string rel_name;
u08 rel_bind_type = -1; //-1 means it didn't resolve
switch (type) switch (type) {
case R_X86_64_RELATIVE:
if (symbol != 0) // should be always zero
{
LOG_INFO_IF(debug_loader, "R_X86_64_RELATIVE symbol not zero = {:#010x}\n", type, symbol);
}
rel_value = rel_base_virtual_addr + addend;
rel_isResolved = true;
break;
case R_X86_64_64:
case R_X86_64_JUMP_SLOT: // similar but addend is not take into account
{
auto sym = symbolsTlb[symbol];
auto sym_bind = sym.GetBind();
auto sym_type = sym.GetType();
auto sym_visibility = sym.GetVisibility();
u64 symbol_vitrual_addr = 0;
SymbolRecord symrec{};
switch (sym_type) {
case STT_FUN: rel_sym_type = 2; break;
case STT_OBJECT: rel_sym_type = 1; break;
default: LOG_INFO_IF(debug_loader, "unknown symbol type {}\n", sym_type);
}
if (sym_visibility != 0) // should be zero log if else
{
LOG_INFO_IF(debug_loader, "symbol visilibity !=0\n");
}
switch (sym_bind) {
case STB_GLOBAL:
rel_bind_type = STB_GLOBAL;
rel_name = namesTlb + sym.st_name;
m->linker->Resolve(rel_name, rel_sym_type, m, &symrec);
symbol_vitrual_addr = symrec.virtual_address;
rel_isResolved = (symbol_vitrual_addr != 0);
rel_name = symrec.name;
if (type == R_X86_64_JUMP_SLOT) {
addend = 0;
}
rel_value = (rel_isResolved ? symbol_vitrual_addr + addend : 0);
if (!rel_isResolved) {
LOG_INFO_IF(debug_loader, "R_X86_64_64-R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type, symbol);
}
break;
default: LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind);
}
} break;
default: LOG_INFO_IF(debug_loader, "UNK type {:#010x} rel symbol : {:#010x}\n", type, symbol);
}
if (rel_isResolved) {
Memory::VirtualMemory::memory_patch(rel_virtual_addr, rel_value);
}
else
{ {
case R_X86_64_RELATIVE: LOG_INFO_IF(debug_loader, "function not patched! {}\n",rel_name);
if (symbol != 0)//should be always zero
{
LOG_INFO_IF(debug_loader, "R_X86_64_RELATIVE symbol not zero = {:#010x}\n", type, symbol);
}
rel_value = rel_base_virtual_addr + addend;
rel_isResolved = true;
break;
case R_X86_64_64:
case R_X86_64_JUMP_SLOT://similar but addend is not take into account
{
auto sym = symbolsTlb[symbol];
auto sym_bind = sym.GetBind();
auto sym_type = sym.GetType();
auto sym_visibility = sym.GetVisibility();
u64 symbol_vitrual_addr = 0;
switch (sym_type)
{
case STT_FUN: rel_sym_type = 2; break;
case STT_OBJECT: rel_sym_type = 1; break;
default:
LOG_INFO_IF(debug_loader, "unknown symbol type {}\n",sym_type);
}
if (sym_visibility != 0)//should be zero log if else
{
LOG_INFO_IF(debug_loader, "symbol visilibity !=0");
}
switch (sym_bind)
{
case STB_GLOBAL:
if (type == R_X86_64_64) {
LOG_INFO_IF(debug_loader, "R_X86_64_64 sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type,symbol);
}
if (type == R_X86_64_JUMP_SLOT) {
LOG_INFO_IF(debug_loader, "R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type,symbol);
}
break;
default:
LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind);
}
}
break;
default:
LOG_INFO_IF(debug_loader, "UNK type {:#010x} rel symbol : {:#010x}\n", type, symbol);
} }
} }
@ -574,3 +586,46 @@ void Linker::Relocate(Module* m)
relocate(idx, rel, m, true); relocate(idx, rel, m, true);
} }
} }
void Linker::Resolve(const std::string& name, int Symtype, Module* m, SymbolRecord* return_info) {
auto ids = StringUtil::split(name, '#');
if (ids.size() == 3) // symbols are 3 parts name , library , module
{
const auto* library = FindLibrary(*m, ids.at(1));
const auto* module = FindModule(*m, ids.at(2));
if (library != nullptr && module != nullptr) {
SymbolRes sr{};
sr.name = ids.at(0);
sr.library = library->name;
sr.library_version = library->version;
sr.module = module->name;
sr.module_version_major = module->version_major;
sr.module_version_minor = module->version_minor;
sr.type = Symtype;
const SymbolRecord* rec = nullptr;
if (m_HLEsymbols != nullptr) {
rec = m_HLEsymbols->FindSymbol(sr);
}
if (rec != nullptr) {
*return_info = *rec;
} else {
return_info->virtual_address = 0;
return_info->name = "Unresolved!!!";
}
}
else
{
__debugbreak();//den tha prepei na ftasoume edo
}
}
else
{
__debugbreak();//oute edo mallon
}
}

View File

@ -5,6 +5,7 @@
#include "Loader/SymbolsResolver.h" #include "Loader/SymbolsResolver.h"
struct DynamicModuleInfo; struct DynamicModuleInfo;
class Linker;
/*this struct keeps neccesary info about loaded modules.Main executeable is included too as well*/ /*this struct keeps neccesary info about loaded modules.Main executeable is included too as well*/
struct Module struct Module
@ -13,6 +14,8 @@ struct Module
u64 aligned_base_size = 0; u64 aligned_base_size = 0;
u64 base_virtual_addr = 0; //base virtual address u64 base_virtual_addr = 0; //base virtual address
Linker* linker = nullptr;
void* m_dynamic = nullptr; void* m_dynamic = nullptr;
void* m_dynamic_data = nullptr; void* m_dynamic_data = nullptr;
DynamicModuleInfo* dynamic_info = nullptr; DynamicModuleInfo* dynamic_info = nullptr;
@ -111,6 +114,7 @@ public:
void LoadSymbols(Module* m); void LoadSymbols(Module* m);
SymbolsResolver* getHLESymbols() { return m_HLEsymbols; } SymbolsResolver* getHLESymbols() { return m_HLEsymbols; }
void Relocate(Module* m); void Relocate(Module* m);
void Resolve(const std::string& name, int Symtype, Module* m, SymbolRecord* return_info);
private: private:
const ModuleInfo* FindModule(const Module& m, const std::string& id); const ModuleInfo* FindModule(const Module& m, const std::string& id);

View File

@ -1,13 +1,32 @@
#include "../../../types.h" #include "../../../types.h"
#include "SymbolsResolver.h" #include "SymbolsResolver.h"
#include "../../../Util/Log.h"
void SymbolsResolver::AddSymbol(const SymbolRes& s, u64 virtual_addr) void SymbolsResolver::AddSymbol(const SymbolRes& s, u64 virtual_addr)
{ {
SymbolRecord r{}; SymbolRecord r{};
char str[256]; r.name = GenerateName(s);
sprintf(str, "%s (%s)[%s_v%d][%s_v%d.%d]", s.name.c_str(),s.nidName.c_str(), s.library.c_str(), s.library_version, s.module.c_str(),s.module_version_major, s.module_version_minor);
r.name = std::string(str);
r.virtual_address = virtual_addr; r.virtual_address = virtual_addr;
m_symbols.push_back(r); m_symbols.push_back(r);
} }
std::string SymbolsResolver::GenerateName(const SymbolRes& s) {
char str[256];
sprintf(str, "%s lib[%s_v%d]mod[%s_v%d.%d]", s.name.c_str(),s.library.c_str(), s.library_version, s.module.c_str(),
s.module_version_major, s.module_version_minor);
return std::string(str);
}
const SymbolRecord* SymbolsResolver::FindSymbol(const SymbolRes& s) const {
std::string name = GenerateName(s);
int index = 0;
for (auto symbol : m_symbols) {
if (symbol.name.compare(name) == 0) {
return &m_symbols.at(index);
}
index++;
}
LOG_INFO_IF(true, "unresolved! {}\n", name);
return nullptr;
}

View File

@ -31,6 +31,9 @@ public:
virtual ~SymbolsResolver() = default; virtual ~SymbolsResolver() = default;
void AddSymbol(const SymbolRes& s, u64 virtual_addr); void AddSymbol(const SymbolRes& s, u64 virtual_addr);
const SymbolRecord* FindSymbol(const SymbolRes& s) const;
static std::string GenerateName(const SymbolRes& s);
private: private:
std::vector<SymbolRecord> m_symbols; std::vector<SymbolRecord> m_symbols;

View File

@ -11207,7 +11207,20 @@ namespace aerolib {
{"TLar1HULv1Q","sceZlibInflate"}, {"TLar1HULv1Q","sceZlibInflate"},
{"m1YErdIXCp4","sceZlibInitialize"}, {"m1YErdIXCp4","sceZlibInitialize"},
{"uB8VlDD4e0s","sceZlibWaitForDone"}, {"uB8VlDD4e0s","sceZlibWaitForDone"},
{"b-Qiqugeo5U","sce_libc_tls_heap"} {"b-Qiqugeo5U","sce_libc_tls_heap"},
//libc
{"P330P3dFF68", "Need_sceLibc"},
{"bzQExy189ZI", "_init_env"},
{"8G2LB+A3rzg", "atexit"},
{"XKRegsFpEpk", "catchReturnFromMain"},
{"uMei1W9uyNo", "exit"},
{"3GPpjQdAMTw", "__cxa_guard_acquire"},
{"9rAeANT2tyE", "__cxa_guard_release"},
{"DfivPArhucg", "memcmp"},
{"Q3VBxCXhUHs", "memcpy"},
//libkernel
{"Ou3iL1abvng", "__stack_chk_fail"},
{"f7uOxY9mM1U", "__stack_chk_guard"}
}; };
}; };

View File

@ -34,7 +34,7 @@
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc == 1) { if (argc == 1) {
printf("Usage: %s <module path>\n", argv[0]); printf("Usage: %s <elf or eboot.bin path>\n", argv[0]);
return -1; return -1;
} }

View File

@ -27,6 +27,8 @@ option(ZYDIS_BUILD_EXAMPLES "" OFF)
set(zydis_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zydis) set(zydis_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zydis)
add_subdirectory(${zydis_DIR}) add_subdirectory(${zydis_DIR})
#========== winpthreads ======================
add_subdirectory(winpthread)
#=================== IMGUI =================== #=================== IMGUI ===================
set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui) set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui)
@ -56,6 +58,6 @@ find_package(OpenGL REQUIRED)
target_link_libraries(IMGUI PUBLIC ${OPENGL_LIBRARIES}) target_link_libraries(IMGUI PUBLIC ${OPENGL_LIBRARIES})
target_link_libraries(IMGUI PUBLIC SDL3-shared ${CMAKE_DL_LIBS} Zydis) target_link_libraries(IMGUI PUBLIC SDL3-shared ${CMAKE_DL_LIBS} Zydis winpthread)

2
third-party/SDL vendored

@ -1 +1 @@
Subproject commit 125e7420ecd2b0d1847aef804f53e614fbc68253 Subproject commit 27556e098ecce54014ed1fc11c1e974ffdf4bc93

2
third-party/fmt vendored

@ -1 +1 @@
Subproject commit de0757b578244e0bf7ac50007fb5e25fcc899c7c Subproject commit 661b23edeb52d400cf5812e7330f14f05c072fab

2
third-party/imgui vendored

@ -1 +1 @@
Subproject commit 4fab72b40e2972f5d56fc884ed5797446238844e Subproject commit 52125a54a57a458e89bc61502010e964add3cdd5

@ -1 +1 @@
Subproject commit 5018ef9677521983bfedb127901284432d1a05a2 Subproject commit 4904822db8770d04444add00a9e155568d3e8bd1

2
third-party/spdlog vendored

@ -1 +1 @@
Subproject commit 5a6b6cafa8d4aee3e6d0dd16a2cae9169141c831 Subproject commit 76dfc7e7c0d3c69d3cdaa3399b63545235ccbb02

1
third-party/winpthread vendored Submodule

@ -0,0 +1 @@
Subproject commit 918de958b720c3ba7bc47f4988609c0109a0f75b

2
third-party/zydis vendored

@ -1 +1 @@
Subproject commit d4c37ae7a9db989495eb66636a65d8d4ff69eb35 Subproject commit a6d0c713b71b5009634868389f0ff551871273d6