MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / LoadUnique32BitSigreturn

Function LoadUnique32BitSigreturn

Source/Tools/LinuxEmulation/VDSO_Emulation.cpp:662–732  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

660}
661
662void LoadUnique32BitSigreturn(VDSOMapping* Mapping, FEX::HLE::SyscallHandler* const Handler) {
663 // Hardcoded to one page for now
664 auto PageSize = sysconf(_SC_PAGESIZE);
665 PageSize = PageSize > 0 ? PageSize : FEXCore::Utils::FEX_PAGE_SIZE;
666 Mapping->OptionalMappingSize = PageSize;
667
668 // First 64bit page
669 constexpr uintptr_t LOCATION_MAX = 0x1'0000'0000;
670
671 // We need to have the sigret handler in the lower 32bits of memory space
672 // Scan top down and try to allocate a location
673 for (size_t Location = 0xFFFF'E000; Location != 0x0; Location -= PageSize) {
674 void* Ptr =
675 ::mmap(reinterpret_cast<void*>(Location), PageSize, PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
676
677 if (Ptr != MAP_FAILED && reinterpret_cast<uintptr_t>(Ptr) >= LOCATION_MAX) {
678 // Failed to map in the lower 32bits
679 // Try again
680 // Can happen in the case that host kernel ignores MAP_FIXED_NOREPLACE
681 ::munmap(Ptr, PageSize);
682 continue;
683 }
684
685 if (Ptr != MAP_FAILED) {
686 Mapping->OptionalSigReturnMapping = Ptr;
687 break;
688 }
689 }
690
691 // Can't do anything about this
692 // Here's hoping the application doesn't use signals
693 if (!Mapping->OptionalSigReturnMapping) {
694 return;
695 }
696
697 // Signal return handlers need to be bit-exact to what the Linux kernel provides in VDSO.
698 // GDB and unwinding libraries key off of these instructions to understand if the stack frame is a signal frame or not.
699 // This two code sections match exactly what libSegFault expects.
700 //
701 // Typically this handlers are provided by the 32-bit VDSO thunk library, but that isn't available in all cases.
702 // Falling back to this generated code segment still allows a backtrace to work, just might not show
703 // the symbol as VDSO since there is no ELF to parse.
704 constexpr std::array<uint8_t, 9> sigreturn_32_code = {
705 0x58, // pop eax
706 0xb8, 0x77, 0x00, 0x00, 0x00, // mov eax, 0x77
707 0xcd, 0x80, // int 0x80
708 0x90, // nop
709 };
710
711 constexpr std::array<uint8_t, 7> rt_sigreturn_32_code = {
712 0xb8, 0xad, 0x00, 0x00, 0x00, // mov eax, 0xad
713 0xcd, 0x80, // int 0x80
714 };
715
716 VDSOPointers.VDSO_kernel_sigreturn = Mapping->OptionalSigReturnMapping;
717 VDSOPointers.VDSO_kernel_rt_sigreturn =
718 reinterpret_cast<void*>(reinterpret_cast<uint64_t>(Mapping->OptionalSigReturnMapping) + sigreturn_32_code.size());
719

Callers 1

LoadVDSOThunksFunction · 0.85

Calls 4

TrackMmapMethod · 0.80
sizeMethod · 0.45

Tested by

no test coverage detected