Skip to content

Commit 3996ec7

Browse files
committed
Syscalls/Common/Thread: Remove lambda
1 parent e53f6d3 commit 3996ec7

File tree

1 file changed

+190
-175
lines changed
  • Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls

1 file changed

+190
-175
lines changed

Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp

Lines changed: 190 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -390,191 +390,206 @@ uint64_t ForkGuest(FEXCore::Core::InternalThreadState* Thread, FEXCore::Core::Cp
390390
}
391391
}
392392

393-
void RegisterThread(FEX::HLE::SyscallHandler* Handler) {
394-
using namespace FEXCore::IR;
395-
396-
REGISTER_SYSCALL_IMPL(rt_sigreturn, [](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
397-
FEX::HLE::_SyscallHandler->GetSignalDelegator()->HandleSignalHandlerReturn(true);
398-
FEX_UNREACHABLE;
399-
});
400-
401-
REGISTER_SYSCALL_IMPL(fork, ([](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
402-
FEX::HLE::clone3_args args {.Type = TypeOfClone::TYPE_CLONE2,
403-
.args = {
404-
.flags = 0,
405-
.pidfd = 0,
406-
.child_tid = 0,
407-
.parent_tid = 0,
408-
.exit_signal = SIGCHLD,
409-
.stack = 0,
410-
.stack_size = 0,
411-
.tls = 0,
412-
.set_tid = 0,
413-
.set_tid_size = 0,
414-
.cgroup = 0,
415-
}};
416-
417-
return ForkGuest(Frame->Thread, Frame, &args);
418-
}));
419-
420-
REGISTER_SYSCALL_IMPL(vfork, ([](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
421-
FEX::HLE::clone3_args args {.Type = TypeOfClone::TYPE_CLONE2,
422-
.args = {
423-
.flags = CLONE_VFORK,
424-
.pidfd = 0,
425-
.child_tid = 0,
426-
.parent_tid = 0,
427-
.exit_signal = SIGCHLD,
428-
.stack = 0,
429-
.stack_size = 0,
430-
.tls = 0,
431-
.set_tid = 0,
432-
.set_tid_size = 0,
433-
.cgroup = 0,
434-
}};
435-
436-
return ForkGuest(Frame->Thread, Frame, &args);
437-
}));
438-
439-
REGISTER_SYSCALL_IMPL(getpgrp, [](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
440-
uint64_t Result = ::getpgrp();
441-
SYSCALL_ERRNO();
442-
});
443-
444-
REGISTER_SYSCALL_IMPL(clone3, ([](FEXCore::Core::CpuStateFrame* Frame, FEX::HLE::kernel_clone3_args* cl_args, size_t size) -> uint64_t {
445-
FEX::HLE::clone3_args args {};
446-
args.Type = TypeOfClone::TYPE_CLONE3;
447-
memcpy(&args.args, cl_args, std::min(sizeof(FEX::HLE::kernel_clone3_args), size));
448-
return CloneHandler(Frame, &args);
449-
}));
450-
451-
REGISTER_SYSCALL_IMPL(exit, [](FEXCore::Core::CpuStateFrame* Frame, int status) -> uint64_t {
452-
// TLS/DTV teardown is something FEX can't control. Disable glibc checking when we leave a pthread.
453-
// Since this thread is hard stopping, we can't track the TLS/DTV teardown in FEX's thread handling.
454-
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator::HardDisable();
455-
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame);
456-
457-
if (ThreadObject->ThreadInfo.clear_child_tid) {
458-
auto Addr = std::atomic_ref<int32_t>(*ThreadObject->ThreadInfo.clear_child_tid);
459-
Addr.store(0);
460-
syscall(SYSCALL_DEF(futex), ThreadObject->ThreadInfo.clear_child_tid, FUTEX_WAKE, ~0ULL, 0, 0, 0);
461-
}
393+
using namespace FEXCore::IR;
462394

463-
ThreadObject->StatusCode = status;
395+
auto rt_sigreturn(FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
396+
FEX::HLE::_SyscallHandler->GetSignalDelegator()->HandleSignalHandlerReturn(true);
397+
FEX_UNREACHABLE;
398+
}
464399

465-
FEX::HLE::_SyscallHandler->UninstallTLSState(ThreadObject);
400+
auto fork(FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
401+
FEX::HLE::clone3_args args {.Type = TypeOfClone::TYPE_CLONE2,
402+
.args = {
403+
.flags = 0,
404+
.pidfd = 0,
405+
.child_tid = 0,
406+
.parent_tid = 0,
407+
.exit_signal = SIGCHLD,
408+
.stack = 0,
409+
.stack_size = 0,
410+
.tls = 0,
411+
.set_tid = 0,
412+
.set_tid_size = 0,
413+
.cgroup = 0,
414+
}};
415+
416+
return ForkGuest(Frame->Thread, Frame, &args);
417+
}
466418

467-
if (ThreadObject->ExecutionThread) {
468-
// If this is a pthread based execution thread, then there is more work to be done.
469-
// Delegate final deletion and cleanup to the pthreads Thread management.
470-
FEX::LinuxEmulation::Threads::LongjumpDeallocateAndExit(ThreadObject, status);
471-
} else {
472-
FEX::HLE::_SyscallHandler->TM.DestroyThread(ThreadObject, true);
473-
FEX::LinuxEmulation::Threads::DeallocateStackObjectAndExit(nullptr, status);
474-
}
475-
// This will never be reached
476-
std::terminate();
477-
});
478-
479-
REGISTER_SYSCALL_IMPL(prctl,
480-
[](FEXCore::Core::CpuStateFrame* Frame, int option, unsigned long arg2, unsigned long arg3, unsigned long arg4,
481-
unsigned long arg5) -> uint64_t {
482-
uint64_t Result {};
419+
auto vfork(FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
420+
FEX::HLE::clone3_args args {.Type = TypeOfClone::TYPE_CLONE2,
421+
.args = {
422+
.flags = CLONE_VFORK,
423+
.pidfd = 0,
424+
.child_tid = 0,
425+
.parent_tid = 0,
426+
.exit_signal = SIGCHLD,
427+
.stack = 0,
428+
.stack_size = 0,
429+
.tls = 0,
430+
.set_tid = 0,
431+
.set_tid_size = 0,
432+
.cgroup = 0,
433+
}};
434+
435+
return ForkGuest(Frame->Thread, Frame, &args);
436+
}
437+
438+
auto getpgrp(FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
439+
uint64_t Result = ::getpgrp();
440+
SYSCALL_ERRNO();
441+
}
442+
443+
auto clone3(FEXCore::Core::CpuStateFrame* Frame, FEX::HLE::kernel_clone3_args* cl_args, size_t size) -> uint64_t {
444+
FEX::HLE::clone3_args args {};
445+
args.Type = TypeOfClone::TYPE_CLONE3;
446+
memcpy(&args.args, cl_args, std::min(sizeof(FEX::HLE::kernel_clone3_args), size));
447+
return CloneHandler(Frame, &args);
448+
}
449+
450+
auto exit(FEXCore::Core::CpuStateFrame* Frame, int status) -> uint64_t {
451+
// TLS/DTV teardown is something FEX can't control. Disable glibc checking when we leave a pthread.
452+
// Since this thread is hard stopping, we can't track the TLS/DTV teardown in FEX's thread handling.
453+
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator::HardDisable();
454+
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame);
455+
456+
if (ThreadObject->ThreadInfo.clear_child_tid) {
457+
auto Addr = std::atomic_ref<int32_t>(*ThreadObject->ThreadInfo.clear_child_tid);
458+
Addr.store(0);
459+
syscall(SYSCALL_DEF(futex), ThreadObject->ThreadInfo.clear_child_tid, FUTEX_WAKE, ~0ULL, 0, 0, 0);
460+
}
461+
462+
ThreadObject->StatusCode = status;
463+
464+
FEX::HLE::_SyscallHandler->UninstallTLSState(ThreadObject);
465+
466+
if (ThreadObject->ExecutionThread) {
467+
// If this is a pthread based execution thread, then there is more work to be done.
468+
// Delegate final deletion and cleanup to the pthreads Thread management.
469+
FEX::LinuxEmulation::Threads::LongjumpDeallocateAndExit(ThreadObject, status);
470+
} else {
471+
FEX::HLE::_SyscallHandler->TM.DestroyThread(ThreadObject, true);
472+
FEX::LinuxEmulation::Threads::DeallocateStackObjectAndExit(nullptr, status);
473+
}
474+
// This will never be reached
475+
std::terminate();
476+
}
477+
478+
auto prctl(FEXCore::Core::CpuStateFrame* Frame, int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
479+
-> uint64_t {
480+
uint64_t Result {};
483481
#ifndef PR_GET_AUXV
484482
#define PR_GET_AUXV 0x41555856
485483
#endif
486-
switch (option) {
487-
case PR_SET_SECCOMP: {
488-
uint32_t Operation {};
489-
if (arg2 == SECCOMP_MODE_STRICT) Operation = SECCOMP_SET_MODE_STRICT;
490-
if (arg2 == SECCOMP_MODE_FILTER) Operation = SECCOMP_SET_MODE_FILTER;
491-
492-
return FEX::HLE::_SyscallHandler->SeccompEmulator.Handle(Frame, Operation, 0, reinterpret_cast<void*>(arg3));
493-
}
494-
case PR_GET_SECCOMP: return FEX::HLE::_SyscallHandler->SeccompEmulator.GetSeccomp(Frame);
495-
case PR_GET_AUXV: {
496-
if (arg4 || arg5) {
497-
return -EINVAL;
498-
}
499-
500-
void* addr = reinterpret_cast<void*>(arg2);
501-
size_t UserSize = reinterpret_cast<size_t>(arg3);
502-
503-
const auto auxv = FEX::HLE::_SyscallHandler->GetCodeLoader()->GetAuxv();
504-
const auto auxvBase = auxv.address;
505-
const auto auxvSize = auxv.size;
506-
size_t MinSize = std::min(auxvSize, UserSize);
507-
508-
memcpy(addr, reinterpret_cast<void*>(auxvBase), MinSize);
509-
510-
// Returns the size of auxv without truncation.
511-
return auxvSize;
512-
}
513-
default: Result = ::prctl(option, arg2, arg3, arg4, arg5); break;
514-
}
515-
SYSCALL_ERRNO();
516-
});
517-
518-
REGISTER_SYSCALL_IMPL(arch_prctl, [](FEXCore::Core::CpuStateFrame* Frame, int code, unsigned long addr) -> uint64_t {
519-
uint64_t Result {};
520-
switch (code) {
521-
case 0x1001: // ARCH_SET_GS
522-
if (addr >= SyscallHandler::TASK_MAX_64BIT) {
523-
// Ignore a non-canonical address
524-
return -EPERM;
525-
}
526-
Frame->State.gs_cached = addr;
527-
Result = 0;
528-
break;
529-
case 0x1002: // ARCH_SET_FS
530-
if (addr >= SyscallHandler::TASK_MAX_64BIT) {
531-
// Ignore a non-canonical address
532-
return -EPERM;
533-
}
534-
Frame->State.fs_cached = addr;
535-
Result = 0;
536-
break;
537-
case 0x1003: // ARCH_GET_FS
538-
*reinterpret_cast<uint64_t*>(addr) = Frame->State.fs_cached;
539-
Result = 0;
540-
break;
541-
case 0x1004: // ARCH_GET_GS
542-
*reinterpret_cast<uint64_t*>(addr) = Frame->State.gs_cached;
543-
Result = 0;
544-
break;
545-
case 0x3001: // ARCH_CET_STATUS
546-
Result = -EINVAL; // We don't support CET, return EINVAL
547-
break;
548-
case 0x1011: // ARCH_GET_CPUID
549-
return 1;
550-
break;
551-
case 0x1012: // ARCH_SET_CPUID
552-
return -ENODEV; // Claim we don't support faulting on CPUID
553-
break;
554-
default:
555-
LogMan::Msg::EFmt("Unknown prctl: 0x{:x}", code);
556-
Result = -EINVAL;
557-
break;
484+
switch (option) {
485+
case PR_SET_SECCOMP: {
486+
uint32_t Operation {};
487+
if (arg2 == SECCOMP_MODE_STRICT) {
488+
Operation = SECCOMP_SET_MODE_STRICT;
489+
}
490+
if (arg2 == SECCOMP_MODE_FILTER) {
491+
Operation = SECCOMP_SET_MODE_FILTER;
492+
}
493+
494+
return FEX::HLE::_SyscallHandler->SeccompEmulator.Handle(Frame, Operation, 0, reinterpret_cast<void*>(arg3));
495+
}
496+
case PR_GET_SECCOMP: return FEX::HLE::_SyscallHandler->SeccompEmulator.GetSeccomp(Frame);
497+
case PR_GET_AUXV: {
498+
if (arg4 || arg5) {
499+
return -EINVAL;
558500
}
559-
SYSCALL_ERRNO();
560-
});
561501

562-
REGISTER_SYSCALL_IMPL(set_tid_address, [](FEXCore::Core::CpuStateFrame* Frame, int* tidptr) -> uint64_t {
563-
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame);
564-
ThreadObject->ThreadInfo.clear_child_tid = tidptr;
565-
return ThreadObject->ThreadInfo.TID;
566-
});
502+
void* addr = reinterpret_cast<void*>(arg2);
503+
size_t UserSize = reinterpret_cast<size_t>(arg3);
567504

568-
REGISTER_SYSCALL_IMPL(exit_group, [](FEXCore::Core::CpuStateFrame* Frame, int status) -> uint64_t {
569-
Frame->Thread->CTX->FlushAndCloseCodeMap();
505+
const auto auxv = FEX::HLE::_SyscallHandler->GetCodeLoader()->GetAuxv();
506+
const auto auxvBase = auxv.address;
507+
const auto auxvSize = auxv.size;
508+
size_t MinSize = std::min(auxvSize, UserSize);
570509

571-
// Save telemetry if we're exiting.
572-
FEX::HLE::_SyscallHandler->GetSignalDelegator()->SaveTelemetry();
573-
FEX::HLE::_SyscallHandler->TM.CleanupForExit();
510+
memcpy(addr, reinterpret_cast<void*>(auxvBase), MinSize);
574511

575-
syscall(SYSCALL_DEF(exit_group), status);
576-
// This will never be reached
577-
std::terminate();
578-
});
512+
// Returns the size of auxv without truncation.
513+
return auxvSize;
514+
}
515+
default: Result = ::prctl(option, arg2, arg3, arg4, arg5); break;
516+
}
517+
SYSCALL_ERRNO();
518+
}
519+
520+
auto arch_prctl(FEXCore::Core::CpuStateFrame* Frame, int code, unsigned long addr) -> uint64_t {
521+
uint64_t Result {};
522+
switch (code) {
523+
case 0x1001: // ARCH_SET_GS
524+
if (addr >= SyscallHandler::TASK_MAX_64BIT) {
525+
// Ignore a non-canonical address
526+
return -EPERM;
527+
}
528+
Frame->State.gs_cached = addr;
529+
Result = 0;
530+
break;
531+
case 0x1002: // ARCH_SET_FS
532+
if (addr >= SyscallHandler::TASK_MAX_64BIT) {
533+
// Ignore a non-canonical address
534+
return -EPERM;
535+
}
536+
Frame->State.fs_cached = addr;
537+
Result = 0;
538+
break;
539+
case 0x1003: // ARCH_GET_FS
540+
*reinterpret_cast<uint64_t*>(addr) = Frame->State.fs_cached;
541+
Result = 0;
542+
break;
543+
case 0x1004: // ARCH_GET_GS
544+
*reinterpret_cast<uint64_t*>(addr) = Frame->State.gs_cached;
545+
Result = 0;
546+
break;
547+
case 0x3001: // ARCH_CET_STATUS
548+
Result = -EINVAL; // We don't support CET, return EINVAL
549+
break;
550+
case 0x1011: // ARCH_GET_CPUID
551+
return 1;
552+
break;
553+
case 0x1012: // ARCH_SET_CPUID
554+
return -ENODEV; // Claim we don't support faulting on CPUID
555+
break;
556+
default:
557+
LogMan::Msg::EFmt("Unknown prctl: 0x{:x}", code);
558+
Result = -EINVAL;
559+
break;
560+
}
561+
SYSCALL_ERRNO();
562+
}
563+
564+
auto set_tid_address(FEXCore::Core::CpuStateFrame* Frame, int* tidptr) -> uint64_t {
565+
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame);
566+
ThreadObject->ThreadInfo.clear_child_tid = tidptr;
567+
return ThreadObject->ThreadInfo.TID;
568+
}
569+
570+
auto exit_group(FEXCore::Core::CpuStateFrame* Frame, int status) -> uint64_t {
571+
Frame->Thread->CTX->FlushAndCloseCodeMap();
572+
573+
// Save telemetry if we're exiting.
574+
FEX::HLE::_SyscallHandler->GetSignalDelegator()->SaveTelemetry();
575+
FEX::HLE::_SyscallHandler->TM.CleanupForExit();
576+
577+
syscall(SYSCALL_DEF(exit_group), status);
578+
// This will never be reached
579+
std::terminate();
580+
}
581+
582+
583+
void RegisterThread(FEX::HLE::SyscallHandler* Handler) {
584+
REGISTER_SYSCALL_IMPL(rt_sigreturn, rt_sigreturn);
585+
REGISTER_SYSCALL_IMPL(fork, fork);
586+
REGISTER_SYSCALL_IMPL(vfork, vfork);
587+
REGISTER_SYSCALL_IMPL(getpgrp, getpgrp);
588+
REGISTER_SYSCALL_IMPL(clone3, clone3);
589+
REGISTER_SYSCALL_IMPL(exit, exit);
590+
REGISTER_SYSCALL_IMPL(prctl, prctl);
591+
REGISTER_SYSCALL_IMPL(arch_prctl, arch_prctl);
592+
REGISTER_SYSCALL_IMPL(set_tid_address, set_tid_address);
593+
REGISTER_SYSCALL_IMPL(exit_group, exit_group);
579594
}
580595
} // namespace FEX::HLE

0 commit comments

Comments
 (0)