mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 05:06:40 +00:00
PS5 graphics (#42)
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
#include "Kyty/Sys/SysDbg.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Kernel/Memory.h"
|
||||
#include "Emulator/Libs/Libs.h"
|
||||
#include "Emulator/Loader/SymbolDatabase.h"
|
||||
#include "Emulator/Loader/VirtualMemory.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs {
|
||||
|
||||
LIB_VERSION("DbgAddressSanitizer", 1, "DbgAddressSanitizer", 1, 1);
|
||||
|
||||
namespace DbgAddressSanitizer {
|
||||
|
||||
struct SourceLocation
|
||||
{
|
||||
const char* filename;
|
||||
int line_no;
|
||||
int column_no;
|
||||
};
|
||||
|
||||
struct Global
|
||||
{
|
||||
uintptr_t beg;
|
||||
uintptr_t size;
|
||||
uintptr_t size_with_redzone;
|
||||
const char* name;
|
||||
const char* module_name;
|
||||
uintptr_t has_dynamic_init;
|
||||
SourceLocation* location;
|
||||
uintptr_t odr_indicator;
|
||||
};
|
||||
|
||||
struct Shadow
|
||||
{
|
||||
uintptr_t start = 0;
|
||||
int count = 0;
|
||||
};
|
||||
|
||||
struct AsanContext
|
||||
{
|
||||
Core::Mutex mutex;
|
||||
Vector<Shadow> shadows;
|
||||
};
|
||||
|
||||
static uint32_t g_fake_stack = 0;
|
||||
static AsanContext* g_ctx = nullptr;
|
||||
|
||||
static void AllocShadow(uintptr_t min_addr, uintptr_t max_addr)
|
||||
{
|
||||
EXIT_IF(g_ctx == nullptr);
|
||||
|
||||
Core::LockGuard lock(g_ctx->mutex);
|
||||
|
||||
static const uintptr_t page_size = 0x10000ull;
|
||||
|
||||
auto min_shadow = ((min_addr >> 3u) + 0x10000000000ull) & ~(page_size - 1);
|
||||
auto max_shadow = ((max_addr >> 3u) + 0x10000000000ull) & ~(page_size - 1);
|
||||
|
||||
auto size = max_shadow - min_shadow + page_size;
|
||||
|
||||
printf("\t shadow = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(min_shadow));
|
||||
printf("\t size = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(size));
|
||||
|
||||
for (uintptr_t page = min_shadow; page <= max_shadow; page += page_size)
|
||||
{
|
||||
if (auto index = g_ctx->shadows.Find(page, [](auto& s, auto p) { return s.start == p; }); g_ctx->shadows.IndexValid(index))
|
||||
{
|
||||
g_ctx->shadows[index].count++;
|
||||
} else
|
||||
{
|
||||
if (!Loader::VirtualMemory::AllocFixed(page, page_size, Loader::VirtualMemory::Mode::ReadWrite))
|
||||
{
|
||||
EXIT("can't allocate shadow memory\n");
|
||||
}
|
||||
|
||||
Shadow s;
|
||||
s.start = page;
|
||||
s.count = 1;
|
||||
g_ctx->shadows.Add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FreeShadow(uintptr_t min_addr, uintptr_t max_addr)
|
||||
{
|
||||
EXIT_IF(g_ctx == nullptr);
|
||||
|
||||
Core::LockGuard lock(g_ctx->mutex);
|
||||
|
||||
static const uintptr_t page_size = 0x10000ull;
|
||||
|
||||
auto min_shadow = ((min_addr >> 3u) + 0x10000000000ull) & ~(page_size - 1);
|
||||
auto max_shadow = ((max_addr >> 3u) + 0x10000000000ull) & ~(page_size - 1);
|
||||
|
||||
auto size = max_shadow - min_shadow + page_size;
|
||||
|
||||
printf("\t shadow = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(min_shadow));
|
||||
printf("\t size = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(size));
|
||||
|
||||
for (uintptr_t page = min_shadow; page <= max_shadow; page += page_size)
|
||||
{
|
||||
if (auto index = g_ctx->shadows.Find(page, [](auto& s, auto p) { return s.start == p; }); g_ctx->shadows.IndexValid(index))
|
||||
{
|
||||
g_ctx->shadows[index].count--;
|
||||
|
||||
if (g_ctx->shadows[index].count <= 0)
|
||||
{
|
||||
if (!Loader::VirtualMemory::Free(page))
|
||||
{
|
||||
EXIT("can't free shadow memory\n");
|
||||
}
|
||||
|
||||
g_ctx->shadows.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void KernelAlloc(uintptr_t addr, size_t size)
|
||||
{
|
||||
AllocShadow(addr, addr + size - 1);
|
||||
}
|
||||
|
||||
static void KernelFree(uintptr_t addr, size_t size)
|
||||
{
|
||||
FreeShadow(addr, addr + size - 1);
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_init()
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(g_ctx != nullptr);
|
||||
|
||||
g_ctx = new AsanContext;
|
||||
|
||||
sys_dbg_stack_info_t s {};
|
||||
sys_stack_usage(s);
|
||||
|
||||
AllocShadow(s.reserved_addr, reinterpret_cast<uintptr_t>(&s));
|
||||
|
||||
LibKernel::Memory::RegisterCallbacks(KernelAlloc, KernelFree);
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_version_mismatch_check_v8()
|
||||
{
|
||||
PRINT_NAME();
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_register_elf_globals(uintptr_t* flag, Global* start, Global* stop)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
printf("\t flag = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(flag));
|
||||
printf("\t start = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(start));
|
||||
printf("\t stop = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(stop));
|
||||
|
||||
if (flag == nullptr || start == nullptr || stop == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (*flag != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto num = stop - start;
|
||||
|
||||
if (num != 0)
|
||||
{
|
||||
uintptr_t min_addr = UINTPTR_MAX;
|
||||
uintptr_t max_addr = 0;
|
||||
|
||||
for (ptrdiff_t i = 0; i < num; i++)
|
||||
{
|
||||
auto* g = start + i;
|
||||
|
||||
printf("asan global:\n");
|
||||
printf("\t beg = %016" PRIx64 "\n", static_cast<uint64_t>(g->beg));
|
||||
printf("\t size = %016" PRIx64 "\n", static_cast<uint64_t>(g->size));
|
||||
printf("\t size_with_redzone = %016" PRIx64 "\n", static_cast<uint64_t>(g->size_with_redzone));
|
||||
printf("\t name = %s\n", g->name);
|
||||
printf("\t module_name = %s\n", g->module_name);
|
||||
printf("\t has_dynamic_init = %" PRIu64 "\n", static_cast<uint64_t>(g->has_dynamic_init));
|
||||
printf("\t odr_indicator = %016" PRIx64 "\n", static_cast<uint64_t>(g->odr_indicator));
|
||||
if (g->location != nullptr)
|
||||
{
|
||||
printf("\t location = %s:%d\n", g->location->filename, g->location->line_no);
|
||||
}
|
||||
|
||||
min_addr = std::min(g->beg, min_addr);
|
||||
max_addr = std::max(g->beg + g->size_with_redzone - 1, max_addr);
|
||||
}
|
||||
|
||||
AllocShadow(min_addr, max_addr);
|
||||
}
|
||||
|
||||
*flag = 0;
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_before_dynamic_init(const char* module_name)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
printf("\t name = %s\n", module_name);
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_after_dynamic_init()
|
||||
{
|
||||
PRINT_NAME();
|
||||
}
|
||||
|
||||
static void* KYTY_SYSV_ABI asan_memcpy(void* dst, const void* src, size_t size)
|
||||
{
|
||||
return std::memcpy(dst, src, size);
|
||||
}
|
||||
|
||||
static void* KYTY_SYSV_ABI asan_memset(void* dst, int ch, size_t size)
|
||||
{
|
||||
return std::memset(dst, ch, size);
|
||||
}
|
||||
|
||||
} // namespace DbgAddressSanitizer
|
||||
|
||||
LIB_DEFINE(InitDbgAddressSanitizer_1)
|
||||
{
|
||||
LIB_OBJECT("OmecxEgrhCs", &DbgAddressSanitizer::g_fake_stack);
|
||||
|
||||
LIB_FUNC("xLoVJKHvRMU", DbgAddressSanitizer::asan_init);
|
||||
LIB_FUNC("GY2I-Okc7q0", DbgAddressSanitizer::asan_version_mismatch_check_v8);
|
||||
LIB_FUNC("W+2HQAGdPuU", DbgAddressSanitizer::asan_register_elf_globals);
|
||||
LIB_FUNC("G9xSYlaNv+Y", DbgAddressSanitizer::asan_before_dynamic_init);
|
||||
LIB_FUNC("z5Gy5T3tptE", DbgAddressSanitizer::asan_after_dynamic_init);
|
||||
LIB_FUNC("g+Neom2EHO8", DbgAddressSanitizer::asan_memcpy);
|
||||
LIB_FUNC("q-hZf47nHhQ", DbgAddressSanitizer::asan_memset);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
@@ -85,6 +85,7 @@ LIB_DEFINE(InitGraphicsDriver_1)
|
||||
LIB_FUNC("wr23dPKyWc0", Gen5::GraphicsCbReleaseMem);
|
||||
LIB_FUNC("TRO721eVt4g", Gen5::GraphicsDcbResetQueue);
|
||||
LIB_FUNC("MWiElSNE8j8", Gen5::GraphicsDcbWaitUntilSafeForRendering);
|
||||
LIB_FUNC("pFLArOT53+w", Gen5::GraphicsDcbSetShRegisterDirect);
|
||||
LIB_FUNC("ZvwO9euwYzc", Gen5::GraphicsDcbSetCxRegistersIndirect);
|
||||
LIB_FUNC("-HOOCn0JY48", Gen5::GraphicsDcbSetShRegistersIndirect);
|
||||
LIB_FUNC("hvUfkUIQcOE", Gen5::GraphicsDcbSetUcRegistersIndirect);
|
||||
|
||||
@@ -243,11 +243,16 @@ static void KYTY_SYSV_ABI KernelRtldSetApplicationHeapAPI(void* api[])
|
||||
[[maybe_unused]] auto* heap_posix_memalign = api[6];
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI write(int d, const char* str, int64_t size)
|
||||
static int64_t KYTY_SYSV_ABI write(int d, const char* str, int64_t size)
|
||||
{
|
||||
// PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(d < 0 || d > 2);
|
||||
EXIT_NOT_IMPLEMENTED(d < 0);
|
||||
|
||||
if (d > 2)
|
||||
{
|
||||
return POSIX_N_CALL(FileSystem::KernelWrite(d, str, size));
|
||||
}
|
||||
|
||||
int size_int = static_cast<int>(size);
|
||||
|
||||
@@ -256,6 +261,18 @@ static int KYTY_SYSV_ABI write(int d, const char* str, int64_t size)
|
||||
return size_int;
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI open(const char* path, int flags, int mode)
|
||||
{
|
||||
return POSIX_N_CALL(FileSystem::KernelOpen(path, flags, mode));
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI close(int d)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(d <= 2);
|
||||
|
||||
return POSIX_CALL(FileSystem::KernelClose(d));
|
||||
}
|
||||
|
||||
static int64_t KYTY_SYSV_ABI read(int d, void* buf, uint64_t nbytes)
|
||||
{
|
||||
// PRINT_NAME();
|
||||
@@ -623,6 +640,7 @@ LIB_DEFINE(InitLibKernel_1)
|
||||
LIB_OBJECT("djxxOmW6-aw", &LibKernel::g_progname);
|
||||
|
||||
LIB_FUNC("1jfXLRVzisc", LibKernel::KernelUsleep);
|
||||
LIB_FUNC("6c3rCVE-fTU", LibKernel::open);
|
||||
LIB_FUNC("6xVpy0Fdq+I", LibKernel::sigprocmask);
|
||||
LIB_FUNC("6Z83sYWFlA8", LibKernel::exit);
|
||||
LIB_FUNC("8OnWXlgQlvo", LibKernel::KernelRtldThreadAtexitDecrement);
|
||||
@@ -636,6 +654,7 @@ LIB_DEFINE(InitLibKernel_1)
|
||||
LIB_FUNC("FxVZqBAA7ks", LibKernel::write);
|
||||
LIB_FUNC("kbw4UHHSYy0", LibKernel::pthread_cxa_finalize);
|
||||
LIB_FUNC("lLMT9vJAck0", LibKernel::clock_gettime);
|
||||
LIB_FUNC("NNtFaKJbPt0", LibKernel::close);
|
||||
LIB_FUNC("OMDRKKAZ8I4", LibKernel::KernelDebugRaiseException);
|
||||
LIB_FUNC("Ou3iL1abvng", LibKernel::stack_chk_fail);
|
||||
LIB_FUNC("p5EcQeEeJAE", LibKernel::KernelRtldSetApplicationHeapAPI);
|
||||
|
||||
@@ -10,6 +10,7 @@ LIB_DEFINE(InitLibcInternal_1);
|
||||
|
||||
LIB_DEFINE(InitAppContent_1);
|
||||
LIB_DEFINE(InitAudio_1);
|
||||
LIB_DEFINE(InitDbgAddressSanitizer_1);
|
||||
LIB_DEFINE(InitDebug_1);
|
||||
LIB_DEFINE(InitDialog_1);
|
||||
LIB_DEFINE(InitDiscMap_1);
|
||||
@@ -26,9 +27,10 @@ LIB_DEFINE(InitVideoOut_1);
|
||||
|
||||
bool Init(const String& id, Loader::SymbolDatabase* s)
|
||||
{
|
||||
LIB_CHECK(U"libAudio_1", InitAudio_1);
|
||||
LIB_CHECK(U"libAppContent_1", InitAppContent_1);
|
||||
LIB_CHECK(U"libAudio_1", InitAudio_1);
|
||||
LIB_CHECK(U"libc_internal_1", LibcInternal::InitLibcInternal_1);
|
||||
LIB_CHECK(U"libDbgAddressSanitizer_1", InitDbgAddressSanitizer_1);
|
||||
LIB_CHECK(U"libDebug_1", InitDebug_1);
|
||||
LIB_CHECK(U"libDialog_1", InitDialog_1);
|
||||
LIB_CHECK(U"libDiscMap_1", InitDiscMap_1);
|
||||
@@ -46,6 +48,27 @@ bool Init(const String& id, Loader::SymbolDatabase* s)
|
||||
return false;
|
||||
}
|
||||
|
||||
void InitAll(Loader::SymbolDatabase* s)
|
||||
{
|
||||
LIB_LOAD(InitAudio_1);
|
||||
LIB_LOAD(InitAppContent_1);
|
||||
LIB_LOAD(LibcInternal::InitLibcInternal_1);
|
||||
LIB_LOAD(InitDbgAddressSanitizer_1);
|
||||
LIB_LOAD(InitDebug_1);
|
||||
LIB_LOAD(InitDialog_1);
|
||||
LIB_LOAD(InitDiscMap_1);
|
||||
LIB_LOAD(InitGraphicsDriver_1);
|
||||
LIB_LOAD(InitLibKernel_1);
|
||||
LIB_LOAD(InitNet_1);
|
||||
LIB_LOAD(InitPad_1);
|
||||
LIB_LOAD(InitPlayGo_1);
|
||||
LIB_LOAD(InitSaveData_1);
|
||||
LIB_LOAD(InitSysmodule_1);
|
||||
LIB_LOAD(InitSystemService_1);
|
||||
LIB_LOAD(InitUserService_1);
|
||||
LIB_LOAD(InitVideoOut_1);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
Reference in New Issue
Block a user