diff --git a/CMakeLists.txt b/CMakeLists.txt index b07d8996..1be51375 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ add_executable(shadps4 src/Core/PS4/HLE/Kernel/cpu_management.cpp src/Core/PS4/HLE/Kernel/cpu_management.h - "src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.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/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" "src/debug.h" "src/Core/PS4/HLE/Kernel/memory_management.cpp" "src/Core/PS4/HLE/Kernel/memory_management.h" "src/Core/PS4/GPU/gpu_memory.cpp" "src/Core/PS4/GPU/gpu_memory.h" "src/emulator.cpp" "src/emulator.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h" "src/Core/PS4/HLE/Graphics/graphics_ctx.h" "src/vulkan_util.cpp" "src/vulkan_util.h" "src/Core/PS4/GPU/video_out_buffer.cpp" "src/Core/PS4/GPU/video_out_buffer.h" "src/Core/PS4/HLE/Graphics/graphics_render.cpp" "src/Core/PS4/HLE/Graphics/graphics_render.h" "src/Core/PS4/GPU/tile_manager.cpp" "src/Core/PS4/GPU/tile_manager.h" "src/version.h") + "src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.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/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" "src/debug.h" "src/Core/PS4/HLE/Kernel/memory_management.cpp" "src/Core/PS4/HLE/Kernel/memory_management.h" "src/Core/PS4/GPU/gpu_memory.cpp" "src/Core/PS4/GPU/gpu_memory.h" "src/emulator.cpp" "src/emulator.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h" "src/Core/PS4/HLE/Graphics/graphics_ctx.h" "src/vulkan_util.cpp" "src/vulkan_util.h" "src/Core/PS4/GPU/video_out_buffer.cpp" "src/Core/PS4/GPU/video_out_buffer.h" "src/Core/PS4/HLE/Graphics/graphics_render.cpp" "src/Core/PS4/HLE/Graphics/graphics_render.h" "src/Core/PS4/GPU/tile_manager.cpp" "src/Core/PS4/GPU/tile_manager.h" "src/version.h" "src/Emulator/HLE/Libraries/LibC/printf.h" "src/Emulator/HLE/Libraries/LibC/va_ctx.h" "src/Emulator/HLE/Libraries/LibC/libc.cpp" "src/Emulator/HLE/Libraries/LibC/libc.h") find_package(OpenGL REQUIRED) target_link_libraries(shadps4 PUBLIC fmt mincore spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY} vulkan-1 spirv-tools-opt spirv-tools) diff --git a/src/Core/PS4/HLE/LibC.cpp b/src/Core/PS4/HLE/LibC.cpp index f6ccc148..4ff9bc27 100644 --- a/src/Core/PS4/HLE/LibC.cpp +++ b/src/Core/PS4/HLE/LibC.cpp @@ -5,6 +5,8 @@ #include "../Loader/Elf.h" #include "Libs.h" +#include "Emulator/HLE/Libraries/LibC/libc.h" + namespace HLE::Libs::LibC { @@ -86,11 +88,6 @@ static PS4_SYSV_ABI int atexit(void (*func)()) { } static PS4_SYSV_ABI void _Assert() { BREAKPOINT(); } -static PS4_SYSV_ABI int printf(const char* s) { - puts(s); - return 0; // not correct -} - 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); @@ -101,7 +98,7 @@ void LibC_Register(SymbolsResolver* sym) { LIB_FUNCTION("uMei1W9uyNo", "libc", 1, "libc", 1, 1, exit); LIB_FUNCTION("8G2LB+A3rzg", "libc", 1, "libc", 1, 1, atexit); LIB_FUNCTION("-QgqOT5u2Vk", "libc", 1, "libc", 1, 1, _Assert); - LIB_FUNCTION("hcuQgD53UxM", "libc", 1, "libc", 1, 1, printf); + LIB_FUNCTION("hcuQgD53UxM", "libc", 1, "libc", 1, 1, Emulator::HLE::Libraries::LibC::printf); LIB_OBJ("P330P3dFF68", "libc", 1, "libc", 1, 1, &HLE::Libs::LibC::g_need_sceLibc); } diff --git a/src/Emulator/HLE/Libraries/LibC/libc.cpp b/src/Emulator/HLE/Libraries/LibC/libc.cpp new file mode 100644 index 00000000..ae9e8eee --- /dev/null +++ b/src/Emulator/HLE/Libraries/LibC/libc.cpp @@ -0,0 +1,9 @@ +#include "libc.h" + +namespace Emulator::HLE::Libraries::LibC { + +PS4_SYSV_ABI int printf(VA_ARGS) { + VA_CTX(ctx); + return printf_ctx(&ctx); +} +}; // namespace Emulator::HLE::Libraries::LibC \ No newline at end of file diff --git a/src/Emulator/HLE/Libraries/LibC/libc.h b/src/Emulator/HLE/Libraries/LibC/libc.h new file mode 100644 index 00000000..4da2bb6e --- /dev/null +++ b/src/Emulator/HLE/Libraries/LibC/libc.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include "printf.h" + +namespace Emulator::HLE::Libraries::LibC { + + //HLE functions + PS4_SYSV_ABI int printf(VA_ARGS); +} \ No newline at end of file diff --git a/src/Emulator/HLE/Libraries/LibC/printf.h b/src/Emulator/HLE/Libraries/LibC/printf.h index 5137255d..7201f079 100644 --- a/src/Emulator/HLE/Libraries/LibC/printf.h +++ b/src/Emulator/HLE/Libraries/LibC/printf.h @@ -56,6 +56,7 @@ #include #include "va_ctx.h" +#include namespace Emulator::HLE::Libraries::LibC { // ntoa conversion buffer size, this must be big enough to hold @@ -671,6 +672,14 @@ static inline int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen return (int)idx; } +static int printf_ctx(VaCtx* ctx) { + const char* format = vaArgPtr(&ctx->va_list); + char buffer[256]; + int result= _vsnprintf(_out_buffer, buffer, (size_t)-1, format, &ctx->va_list); + puts(buffer); + return result; +} + #if 0 /////////////////////////////////////////////////////// diff --git a/src/Emulator/HLE/Libraries/LibC/va_ctx.h b/src/Emulator/HLE/Libraries/LibC/va_ctx.h index 2dd613bc..a2d78a52 100644 --- a/src/Emulator/HLE/Libraries/LibC/va_ctx.h +++ b/src/Emulator/HLE/Libraries/LibC/va_ctx.h @@ -1,4 +1,30 @@ #include +#include + +#define VA_ARGS \ + uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9, uint64_t overflow_arg_area, __m128 xmm0, __m128 xmm1, \ + __m128 xmm2, __m128 xmm3, __m128 xmm4, __m128 xmm5, __m128 xmm6, __m128 xmm7, ... + +#define VA_CTX(ctx) \ + alignas(16) VaCtx ctx; \ + (ctx).reg_save_area.gp[0] = rdi; \ + (ctx).reg_save_area.gp[1] = rsi; \ + (ctx).reg_save_area.gp[2] = rdx; \ + (ctx).reg_save_area.gp[3] = rcx; \ + (ctx).reg_save_area.gp[4] = r8; \ + (ctx).reg_save_area.gp[5] = r9; \ + (ctx).reg_save_area.fp[0] = xmm0; \ + (ctx).reg_save_area.fp[1] = xmm1; \ + (ctx).reg_save_area.fp[2] = xmm2; \ + (ctx).reg_save_area.fp[3] = xmm3; \ + (ctx).reg_save_area.fp[4] = xmm4; \ + (ctx).reg_save_area.fp[5] = xmm5; \ + (ctx).reg_save_area.fp[6] = xmm6; \ + (ctx).reg_save_area.fp[7] = xmm7; \ + (ctx).va_list.reg_save_area = &(ctx).reg_save_area; \ + (ctx).va_list.gp_offset = offsetof(VaRegSave, gp); \ + (ctx).va_list.fp_offset = offsetof(VaRegSave, fp); \ + (ctx).va_list.overflow_arg_area = &overflow_arg_area; namespace Emulator::HLE::Libraries::LibC { @@ -11,15 +37,25 @@ struct VaList { void* reg_save_area; }; +struct VaRegSave { + u64 gp[6]; + __m128 fp[8]; +}; + +struct VaCtx { + VaRegSave reg_save_area; + VaList va_list; +}; + template T vaArgRegSaveAreaGp(VaList* l) { - auto* addr = reinterpret_cast(static_cast(l->reg_save_area) + l->gp_offset); + auto* addr = reinterpret_cast(static_cast(l->reg_save_area) + l->gp_offset); l->gp_offset += Size; return *addr; } -template +template T vaArgOverflowArgArea(VaList* l) { - auto ptr = ((reinterpret_cast(l->overflow_arg_area) + (Align - 1)) & ~(Align - 1)); + auto ptr = ((reinterpret_cast(l->overflow_arg_area) + (Align - 1)) & ~(Align - 1)); auto* addr = reinterpret_cast(ptr); l->overflow_arg_area = reinterpret_cast(ptr + Size); return *addr; @@ -27,7 +63,7 @@ T vaArgOverflowArgArea(VaList* l) { template T vaArgRegSaveAreaFp(VaList* l) { - auto* addr = reinterpret_cast(static_cast(l->reg_save_area) + l->fp_offset); + auto* addr = reinterpret_cast(static_cast(l->reg_save_area) + l->fp_offset); l->fp_offset += Size; return *addr; }