shadPS4/src/core/libraries/kernel/kernel.cpp
georgemoralis bb59cd81fa
[Libs] sceNet (#2815)
* implemented sceNetGetMacAddress

* added all error codes

* added ORBIS_NET_CTL_INFO_DEVICE , ORBIS_NET_CTL_INFO_MTU

* RE sceNetConnect

* sceNetBind RE

* RE sceNetAccept

* RE sceNetGetpeername ,sceNetGetsockname

* fixup

* RE sceNetListen ,sceNetSetsockopt

* sceNetShutdown,sceNetSocket,sceNetSocketAbort,sceNetSocketClose

* sceSend,sceSendTo,sceSendMsg

* sceNetRecv,sceNetRecvFrom,sceNetRecvMsg RE

* some kernel net calls

* init winsock2

* logging

* sockets interface

* added winsock to SCE* error codes conversion

* implemented net basic calls

* some net calls implementation

* clang fixes

* fixes for linux+macOS

* more fix

* added sys_accept implementation

* more posix net calls

* implemented sys_getsockname

* fixed redirection

* fixed posix socket?

* posix_sendto , recvfrom

* added sys_socketclose

* unsigned error log

* added setsocketoptions

* added more posix net calls

* implement getsocketOptions

* stubbed p2p calls
2025-04-30 17:58:39 +03:00

254 lines
8.1 KiB
C++

// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <thread>
#include <boost/asio/io_context.hpp>
#include "common/assert.h"
#include "common/debug.h"
#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/debug.h"
#include "core/libraries/kernel/equeue.h"
#include "core/libraries/kernel/file_system.h"
#include "core/libraries/kernel/kernel.h"
#include "core/libraries/kernel/memory.h"
#include "core/libraries/kernel/orbis_error.h"
#include "core/libraries/kernel/posix_error.h"
#include "core/libraries/kernel/process.h"
#include "core/libraries/kernel/threads.h"
#include "core/libraries/kernel/threads/exception.h"
#include "core/libraries/kernel/time.h"
#include "core/libraries/libs.h"
#include "core/libraries/network/sys_net.h"
#ifdef _WIN64
#include <Rpc.h>
#endif
#include <common/singleton.h>
#include "aio.h"
namespace Libraries::Kernel {
static u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; // dummy return
boost::asio::io_context io_context;
static std::mutex m_asio_req;
static std::condition_variable_any cv_asio_req;
static std::atomic<u32> asio_requests;
static std::jthread service_thread;
void KernelSignalRequest() {
std::unique_lock lock{m_asio_req};
++asio_requests;
cv_asio_req.notify_one();
}
static void KernelServiceThread(std::stop_token stoken) {
Common::SetCurrentThreadName("shadPS4:KernelServiceThread");
while (!stoken.stop_requested()) {
HLE_TRACE;
{
std::unique_lock lock{m_asio_req};
Common::CondvarWait(cv_asio_req, lock, stoken, [] { return asio_requests != 0; });
}
if (stoken.stop_requested()) {
break;
}
io_context.run();
io_context.restart();
asio_requests = 0;
}
}
static PS4_SYSV_ABI void stack_chk_fail() {
UNREACHABLE();
}
static thread_local int g_posix_errno = 0;
int* PS4_SYSV_ABI __Error() {
return &g_posix_errno;
}
void ErrSceToPosix(int error) {
g_posix_errno = error - ORBIS_KERNEL_ERROR_UNKNOWN;
}
int ErrnoToSceKernelError(int error) {
return error + ORBIS_KERNEL_ERROR_UNKNOWN;
}
void SetPosixErrno(int e) {
// Some error numbers are different between supported OSes
switch (e) {
case EPERM:
g_posix_errno = POSIX_EPERM;
break;
case ENOENT:
g_posix_errno = POSIX_ENOENT;
break;
case EDEADLK:
g_posix_errno = POSIX_EDEADLK;
break;
case ENOMEM:
g_posix_errno = POSIX_ENOMEM;
break;
case EACCES:
g_posix_errno = POSIX_EACCES;
break;
case EINVAL:
g_posix_errno = POSIX_EINVAL;
break;
case ENOSPC:
g_posix_errno = POSIX_ENOSPC;
break;
case ERANGE:
g_posix_errno = POSIX_ERANGE;
break;
case EAGAIN:
g_posix_errno = POSIX_EAGAIN;
break;
case ETIMEDOUT:
g_posix_errno = POSIX_ETIMEDOUT;
break;
default:
LOG_WARNING(Kernel, "Unhandled errno {}", e);
g_posix_errno = e;
}
}
static uint64_t g_mspace_atomic_id_mask = 0;
static uint64_t g_mstate_table[64] = {0};
struct HeapInfoInfo {
uint64_t size = sizeof(HeapInfoInfo);
uint32_t flag;
uint32_t getSegmentInfo;
uint64_t* mspace_atomic_id_mask;
uint64_t* mstate_table;
};
void PS4_SYSV_ABI sceLibcHeapGetTraceInfo(HeapInfoInfo* info) {
info->mspace_atomic_id_mask = &g_mspace_atomic_id_mask;
info->mstate_table = g_mstate_table;
info->getSegmentInfo = 0;
}
struct OrbisKernelUuid {
u32 timeLow;
u16 timeMid;
u16 timeHiAndVersion;
u8 clockSeqHiAndReserved;
u8 clockSeqLow;
u8 node[6];
};
int PS4_SYSV_ABI sceKernelUuidCreate(OrbisKernelUuid* orbisUuid) {
#ifdef _WIN64
UUID uuid;
UuidCreate(&uuid);
orbisUuid->timeLow = uuid.Data1;
orbisUuid->timeMid = uuid.Data2;
orbisUuid->timeHiAndVersion = uuid.Data3;
orbisUuid->clockSeqHiAndReserved = uuid.Data4[0];
orbisUuid->clockSeqLow = uuid.Data4[1];
for (int i = 0; i < 6; i++) {
orbisUuid->node[i] = uuid.Data4[2 + i];
}
#else
LOG_ERROR(Kernel, "sceKernelUuidCreate: Add linux");
#endif
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;
}
int PS4_SYSV_ABI _sigprocmask() {
return ORBIS_OK;
}
int PS4_SYSV_ABI posix_getpagesize() {
return 16_KB;
}
void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
service_thread = std::jthread{KernelServiceThread};
Libraries::Kernel::RegisterFileSystem(sym);
Libraries::Kernel::RegisterTime(sym);
Libraries::Kernel::RegisterThreads(sym);
Libraries::Kernel::RegisterKernelEventFlag(sym);
Libraries::Kernel::RegisterMemory(sym);
Libraries::Kernel::RegisterEventQueue(sym);
Libraries::Kernel::RegisterProcess(sym);
Libraries::Kernel::RegisterException(sym);
Libraries::Kernel::RegisterAio(sym);
Libraries::Kernel::RegisterDebug(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("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("k+AXqu2-eBc", "libkernel", 1, "libkernel", 1, 1, posix_getpagesize);
LIB_FUNCTION("k+AXqu2-eBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpagesize);
LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1,
sceLibcHeapGetTraceInfo);
// network
LIB_FUNCTION("XVL8So3QJUk", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_connect);
LIB_FUNCTION("TU-d9PfIHPM", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_socketex);
LIB_FUNCTION("KuOmgKoqCdY", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
LIB_FUNCTION("pxnCmagrtao", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_listen);
LIB_FUNCTION("3e+4Iv7IJ8U", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_accept);
LIB_FUNCTION("TU-d9PfIHPM", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_socket);
LIB_FUNCTION("oBr313PppNE", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_sendto);
LIB_FUNCTION("lUk6wrGXyMw", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_recvfrom);
LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sys_setsockopt);
LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sys_getsockname);
LIB_FUNCTION("KuOmgKoqCdY", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
LIB_FUNCTION("5jRCs2axtr4", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...
LIB_FUNCTION("4n51s0zEf0c", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sceNetInetPton); // TODO fix it to sys_ ...
}
} // namespace Libraries::Kernel