diff --git a/src/core/file_sys/directories/base_directory.h b/src/core/file_sys/directories/base_directory.h index 8900ac32b..b412865a2 100644 --- a/src/core/file_sys/directories/base_directory.h +++ b/src/core/file_sys/directories/base_directory.h @@ -36,6 +36,18 @@ public: return ORBIS_KERNEL_ERROR_EBADF; } + virtual s64 write(const void* buf, u64 nbytes) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + virtual s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + virtual s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) { + return ORBIS_KERNEL_ERROR_EBADF; + } + virtual s64 lseek(s64 offset, s32 whence) { return ORBIS_KERNEL_ERROR_EBADF; } diff --git a/src/core/libraries/fiber/fiber.cpp b/src/core/libraries/fiber/fiber.cpp index 7d35add4e..776792041 100644 --- a/src/core/libraries/fiber/fiber.cpp +++ b/src/core/libraries/fiber/fiber.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "fiber.h" @@ -6,8 +6,8 @@ #include "common/elf_info.h" #include "common/logging/log.h" #include "core/libraries/fiber/fiber_error.h" +#include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/libs.h" -#include "core/tls.h" namespace Libraries::Fiber { @@ -20,7 +20,7 @@ static constexpr u64 kFiberStackSizeCheck = 0xdeadbeefdeadbeef; static std::atomic context_size_check = false; OrbisFiberContext* GetFiberContext() { - return Core::GetTcbBase()->tcb_fiber; + return Libraries::Kernel::g_curthread->tcb->tcb_fiber; } extern "C" s32 PS4_SYSV_ABI _sceFiberSetJmp(OrbisFiberContext* ctx) asm("_sceFiberSetJmp"); @@ -269,7 +269,7 @@ s32 PS4_SYSV_ABI sceFiberRunImpl(OrbisFiber* fiber, void* addr_context, u64 size return ORBIS_FIBER_ERROR_INVALID; } - Core::Tcb* tcb = Core::GetTcbBase(); + Core::Tcb* tcb = Libraries::Kernel::g_curthread->tcb; if (tcb->tcb_fiber) { return ORBIS_FIBER_ERROR_PERMISSION; } diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 7ded1f33e..b4c342f18 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -311,6 +311,9 @@ s64 PS4_SYSV_ABI write(s32 fd, const void* buf, u64 nbytes) { } else if (file->type == Core::FileSys::FileType::Socket) { // Socket functions handle errnos internally. return file->socket->SendPacket(buf, nbytes, 0, nullptr, 0); + } else if (file->type == Core::FileSys::FileType::Directory) { + *__Error() = POSIX_EBADF; + return -1; } return file->f.WriteRaw(buf, nbytes); @@ -405,7 +408,11 @@ s64 PS4_SYSV_ABI writev(s32 fd, const OrbisKernelIovec* iov, s32 iovcnt) { return -1; } return result; + } else if (file->type == Core::FileSys::FileType::Directory) { + *__Error() = POSIX_EBADF; + return -1; } + s64 total_written = 0; for (s32 i = 0; i < iovcnt; i++) { total_written += file->f.WriteRaw(iov[i].iov_base, iov[i].iov_len); @@ -1047,7 +1054,11 @@ s64 PS4_SYSV_ABI posix_pwritev(s32 fd, const OrbisKernelIovec* iov, s32 iovcnt, return -1; } return result; + } else if (file->type == Core::FileSys::FileType::Directory) { + *__Error() = POSIX_EBADF; + return -1; } + const s64 pos = file->f.Tell(); SCOPE_EXIT { file->f.Seek(pos); diff --git a/src/core/linker.cpp b/src/core/linker.cpp index ac6b37769..b7c9a2895 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -368,7 +368,7 @@ bool Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Modul void* Linker::TlsGetAddr(u64 module_index, u64 offset) { std::scoped_lock lk{mutex}; - DtvEntry* dtv_table = GetTcbBase()->tcb_dtv; + DtvEntry* dtv_table = Libraries::Kernel::g_curthread->tcb->tcb_dtv; if (dtv_table[0].counter != dtv_generation_counter) { // Generation counter changed, a dynamic module was either loaded or unloaded. const u32 old_num_dtvs = dtv_table[1].counter; @@ -381,7 +381,7 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) { delete[] dtv_table; // Update TCB pointer. - GetTcbBase()->tcb_dtv = new_dtv_table; + Libraries::Kernel::g_curthread->tcb->tcb_dtv = new_dtv_table; dtv_table = new_dtv_table; } diff --git a/src/core/tls.cpp b/src/core/tls.cpp index 2f7e1a1fd..bcefd6f25 100644 --- a/src/core/tls.cpp +++ b/src/core/tls.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -46,10 +46,6 @@ void SetTcbBase(void* image_address) { ASSERT(result != 0); } -Tcb* GetTcbBase() { - return reinterpret_cast(TlsGetValue(GetTcbKey())); -} - #elif defined(__APPLE__) && defined(ARCH_X86_64) // Apple x86_64 @@ -149,12 +145,6 @@ void SetTcbBase(void* image_address) { "Failed to store thread LDT page pointer: {}", errno); } -Tcb* GetTcbBase() { - Tcb* tcb; - asm volatile("mov %%fs:0x0, %0" : "=r"(tcb)); - return tcb; -} - #elif defined(ARCH_X86_64) // Other POSIX x86_64 @@ -164,13 +154,6 @@ void SetTcbBase(void* image_address) { ASSERT_MSG(ret == 0, "Failed to set GS base: errno {}", errno); } -Tcb* GetTcbBase() { - void* tcb = nullptr; - const int ret = syscall(SYS_arch_prctl, ARCH_GET_GS, &tcb); - ASSERT_MSG(ret == 0, "Failed to get GS base: errno {}", errno); - return static_cast(tcb); -} - #else // POSIX non-x86_64 @@ -193,10 +176,6 @@ void SetTcbBase(void* image_address) { ASSERT(pthread_setspecific(GetTcbKey(), image_address) == 0); } -Tcb* GetTcbBase() { - return static_cast(pthread_getspecific(GetTcbKey())); -} - #endif thread_local std::once_flag init_tls_flag; diff --git a/src/core/tls.h b/src/core/tls.h index 787744cd3..6be9752b0 100644 --- a/src/core/tls.h +++ b/src/core/tls.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -36,9 +36,6 @@ u32 GetTcbKey(); /// Sets the data pointer to the TCB block. void SetTcbBase(void* image_address); -/// Retrieves Tcb structure for the calling thread. -Tcb* GetTcbBase(); - /// Makes sure TLS is initialized for the thread before entering guest. void EnsureThreadInitialized(); diff --git a/src/emulator.cpp b/src/emulator.cpp index ad407f9b6..fb187cfae 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -58,10 +58,11 @@ Frontend::WindowSDL* g_window = nullptr; namespace Core { Emulator::Emulator() { - // Initialize NT API functions and set high priority + // Initialize NT API functions, set high priority and disable WER #ifdef _WIN32 Common::NtApi::Initialize(); SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); + SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); // need to init this in order for winsock2 to work WORD versionWanted = MAKEWORD(2, 2); WSADATA wsaData;