mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-09 20:18:19 +03:00
Virtual device abstraction (#1577)
* IOFile: removes seek limit checks when file is writable * add virtual devices scaffold * add stdin/out/err as virtual devices * fixed some merging issues * clang-fix --------- Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
parent
c019b54fec
commit
2380f2f9c9
18 changed files with 687 additions and 77 deletions
|
@ -9,6 +9,9 @@
|
|||
#include "common/logging/log.h"
|
||||
#include "common/polyfill_thread.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/va_ctx.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/equeue.h"
|
||||
#include "core/libraries/kernel/file_system.h"
|
||||
#include "core/libraries/kernel/kernel.h"
|
||||
|
@ -24,6 +27,7 @@
|
|||
#ifdef _WIN64
|
||||
#include <Rpc.h>
|
||||
#endif
|
||||
#include <common/singleton.h>
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
|
@ -65,19 +69,6 @@ static PS4_SYSV_ABI void stack_chk_fail() {
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
struct iovec {
|
||||
void* iov_base; /* Base address. */
|
||||
size_t iov_len; /* Length. */
|
||||
};
|
||||
|
||||
size_t PS4_SYSV_ABI _writev(int fd, const struct iovec* iov, int iovcn) {
|
||||
size_t total_written = 0;
|
||||
for (int i = 0; i < iovcn; i++) {
|
||||
total_written += ::fwrite(iov[i].iov_base, 1, iov[i].iov_len, stdout);
|
||||
}
|
||||
return total_written;
|
||||
}
|
||||
|
||||
static thread_local int g_posix_errno = 0;
|
||||
|
||||
int* PS4_SYSV_ABI __Error() {
|
||||
|
@ -142,24 +133,33 @@ void PS4_SYSV_ABI sceLibcHeapGetTraceInfo(HeapInfoInfo* info) {
|
|||
}
|
||||
|
||||
s64 PS4_SYSV_ABI ps4__write(int d, const char* buf, std::size_t nbytes) {
|
||||
if (d <= 2) { // stdin,stdout,stderr
|
||||
std::string_view str{buf};
|
||||
if (str[nbytes - 1] == '\n') {
|
||||
str = str.substr(0, nbytes - 1);
|
||||
}
|
||||
LOG_INFO(Tty, "{}", str);
|
||||
return nbytes;
|
||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||
auto* file = h->GetFile(d);
|
||||
if (file == nullptr) {
|
||||
return ORBIS_KERNEL_ERROR_EBADF;
|
||||
}
|
||||
LOG_ERROR(Kernel, "(STUBBED) called d = {} nbytes = {} ", d, nbytes);
|
||||
UNREACHABLE();
|
||||
return ORBIS_OK;
|
||||
std::scoped_lock lk{file->m_mutex};
|
||||
if (file->type == Core::FileSys::FileType::Device) {
|
||||
return file->device->write(buf, nbytes);
|
||||
}
|
||||
return file->f.WriteRaw<u8>(buf, nbytes);
|
||||
}
|
||||
|
||||
s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) {
|
||||
ASSERT_MSG(d == 0, "d is not 0!");
|
||||
|
||||
return static_cast<s64>(
|
||||
strlen(std::fgets(static_cast<char*>(buf), static_cast<int>(nbytes), stdin)));
|
||||
if (d == 0) {
|
||||
return static_cast<s64>(
|
||||
strlen(std::fgets(static_cast<char*>(buf), static_cast<int>(nbytes), stdin)));
|
||||
}
|
||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||
auto* file = h->GetFile(d);
|
||||
if (file == nullptr) {
|
||||
return ORBIS_KERNEL_ERROR_EBADF;
|
||||
}
|
||||
std::scoped_lock lk{file->m_mutex};
|
||||
if (file->type == Core::FileSys::FileType::Device) {
|
||||
return file->device->read(buf, nbytes);
|
||||
}
|
||||
return file->f.ReadRaw<u8>(buf, nbytes);
|
||||
}
|
||||
|
||||
struct OrbisKernelUuid {
|
||||
|
@ -189,6 +189,29 @@ int PS4_SYSV_ABI sceKernelUuidCreate(OrbisKernelUuid* orbisUuid) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI kernel_ioctl(int fd, u64 cmd, VA_ARGS) {
|
||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||
auto* file = h->GetFile(fd);
|
||||
if (file == nullptr) {
|
||||
LOG_INFO(Lib_Kernel, "ioctl: fd = {:X} cmd = {:X} file == nullptr", fd, cmd);
|
||||
g_posix_errno = POSIX_EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (file->type != Core::FileSys::FileType::Device) {
|
||||
LOG_WARNING(Lib_Kernel, "ioctl: fd = {:X} cmd = {:X} file->type != Device", fd, cmd);
|
||||
g_posix_errno = ENOTTY;
|
||||
return -1;
|
||||
}
|
||||
VA_CTX(ctx);
|
||||
int result = file->device->ioctl(cmd, &ctx);
|
||||
LOG_TRACE(Lib_Kernel, "ioctl: fd = {:X} cmd = {:X} result = {}", fd, cmd, result);
|
||||
if (result < 0) {
|
||||
ErrSceToPosix(result);
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* PS4_SYSV_ABI sceKernelGetFsSandboxRandomWord() {
|
||||
const char* path = "sys";
|
||||
return path;
|
||||
|
@ -219,13 +242,13 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
|
|||
Libraries::Kernel::RegisterException(sym);
|
||||
|
||||
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
||||
LIB_FUNCTION("PfccT7qURYE", "libkernel", 1, "libkernel", 1, 1, kernel_ioctl);
|
||||
LIB_FUNCTION("JGfTMBOdUJo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetFsSandboxRandomWord);
|
||||
LIB_FUNCTION("XVL8So3QJUk", "libkernel", 1, "libkernel", 1, 1, posix_connect);
|
||||
LIB_FUNCTION("6xVpy0Fdq+I", "libkernel", 1, "libkernel", 1, 1, _sigprocmask);
|
||||
LIB_FUNCTION("Xjoosiw+XPI", "libkernel", 1, "libkernel", 1, 1, sceKernelUuidCreate);
|
||||
LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail);
|
||||
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error);
|
||||
LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev);
|
||||
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
|
||||
LIB_FUNCTION("k+AXqu2-eBc", "libkernel", 1, "libkernel", 1, 1, posix_getpagesize);
|
||||
LIB_FUNCTION("k+AXqu2-eBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpagesize);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue