Skip to content

Commit b8e7fca

Browse files
committed
Syscalls/Common/Thread: Remove lambda
1 parent a086450 commit b8e7fca

1 file changed

Lines changed: 190 additions & 175 deletions

File tree

  • Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls

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

Lines changed: 190 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -393,191 +393,206 @@ uint64_t ForkGuest(FEXCore::Core::InternalThreadState* Thread, FEXCore::Core::Cp
393393
}
394394
}
395395

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

466-
ThreadObject->StatusCode = status;
398+
auto rt_sigreturn(FEXCore::Core::CpuStateFrame* Frame) -> uint64_t {
399+
FEX::HLE::_SyscallHandler->GetSignalDelegator()->HandleSignalHandlerReturn(true);
400+
FEX_UNREACHABLE;
401+
}
467402

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

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

565-
REGISTER_SYSCALL_IMPL(set_tid_address, [](FEXCore::Core::CpuStateFrame* Frame, int* tidptr) -> uint64_t {
566-
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame);
567-
ThreadObject->ThreadInfo.clear_child_tid = tidptr;
568-
return ThreadObject->ThreadInfo.TID;
569-
});
505+
void* addr = reinterpret_cast<void*>(arg2);
506+
size_t UserSize = reinterpret_cast<size_t>(arg3);
570507

571-
REGISTER_SYSCALL_IMPL(exit_group, [](FEXCore::Core::CpuStateFrame* Frame, int status) -> uint64_t {
572-
Frame->Thread->CTX->FlushAndCloseCodeMap();
508+
const auto auxv = FEX::HLE::_SyscallHandler->GetCodeLoader()->GetAuxv();
509+
const auto auxvBase = auxv.address;
510+
const auto auxvSize = auxv.size;
511+
size_t MinSize = std::min(auxvSize, UserSize);
573512

574-
// Save telemetry if we're exiting.
575-
FEX::HLE::_SyscallHandler->GetSignalDelegator()->SaveTelemetry();
576-
FEX::HLE::_SyscallHandler->TM.CleanupForExit();
513+
memcpy(addr, reinterpret_cast<void*>(auxvBase), MinSize);
577514

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

0 commit comments

Comments
 (0)