mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-09 16:00:20 +02:00
Which requires moving LinuxEmulation to its own independent folder as well. Since both IRLoader and FEXLoader rely on it. No functional change, just moves the the code around.
93 lines
2.7 KiB
C++
93 lines
2.7 KiB
C++
// SPDX-License-Identifier: MIT
|
|
/*
|
|
$info$
|
|
tags: LinuxSyscalls|syscalls-x86-64
|
|
$end_info$
|
|
*/
|
|
|
|
#include "LinuxSyscalls/Syscalls.h"
|
|
#include "LinuxSyscalls/x64/Syscalls.h"
|
|
#include "LinuxSyscalls/x64/Types.h"
|
|
|
|
#include <FEXHeaderUtils/Syscalls.h>
|
|
|
|
#include <linux/sem.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
namespace FEXCore::Core {
|
|
struct CpuStateFrame;
|
|
}
|
|
|
|
ARG_TO_STR(FEX::HLE::x64::semun, "%lx")
|
|
|
|
namespace FEX::HLE::x64 {
|
|
void RegisterSemaphore(FEX::HLE::SyscallHandler *Handler) {
|
|
REGISTER_SYSCALL_IMPL_X64_PASS(semop, [](FEXCore::Core::CpuStateFrame *Frame, int semid, struct sembuf *sops, size_t nsops) -> uint64_t {
|
|
uint64_t Result = ::syscall(SYSCALL_DEF(semop), semid, sops, nsops);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_X64_PASS(semtimedop, [](FEXCore::Core::CpuStateFrame *Frame, int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) -> uint64_t {
|
|
uint64_t Result = ::syscall(SYSCALL_DEF(semtimedop), semid, sops, nsops, timeout);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_X64(semctl, [](FEXCore::Core::CpuStateFrame *Frame, int semid, int semnum, int cmd, FEX::HLE::x64::semun semun) -> uint64_t {
|
|
uint64_t Result{};
|
|
switch (cmd) {
|
|
case IPC_SET: {
|
|
struct semid64_ds buf{};
|
|
buf = *semun.buf;
|
|
Result = ::syscall(SYSCALL_DEF(semctl), semid, semnum, cmd, &buf);
|
|
if (Result != -1) {
|
|
*semun.buf = buf;
|
|
}
|
|
break;
|
|
}
|
|
case SEM_STAT:
|
|
case SEM_STAT_ANY:
|
|
case IPC_STAT: {
|
|
struct semid64_ds buf{};
|
|
Result = ::syscall(SYSCALL_DEF(semctl), semid, semnum, cmd, &buf);
|
|
if (Result != -1) {
|
|
*semun.buf = buf;
|
|
}
|
|
break;
|
|
}
|
|
case SEM_INFO:
|
|
case IPC_INFO: {
|
|
struct fex_seminfo si{};
|
|
Result = ::syscall(SYSCALL_DEF(semctl), semid, semnum, cmd, &si);
|
|
if (Result != -1) {
|
|
memcpy(semun.__buf, &si, sizeof(si));
|
|
}
|
|
break;
|
|
}
|
|
case GETALL:
|
|
case SETALL: {
|
|
// ptr is just a int32_t* in this case
|
|
Result = ::syscall(SYSCALL_DEF(semctl), semid, semnum, cmd, semun.array);
|
|
break;
|
|
}
|
|
case SETVAL: {
|
|
// ptr is just a int32_t in this case
|
|
Result = ::syscall(SYSCALL_DEF(semctl), semid, semnum, cmd, semun.val);
|
|
break;
|
|
}
|
|
case IPC_RMID:
|
|
case GETPID:
|
|
case GETNCNT:
|
|
case GETZCNT:
|
|
case GETVAL:
|
|
Result = ::syscall(SYSCALL_DEF(semctl), semid, semnum, cmd, semun);
|
|
break;
|
|
default:
|
|
LOGMAN_MSG_A_FMT("Unhandled semctl cmd: {}", cmd);
|
|
return -EINVAL;
|
|
}
|
|
SYSCALL_ERRNO();
|
|
});
|
|
}
|
|
}
|