/** * @file PlatformIntrinsics.c * @author Sina Karvandi (sina@hyperdbg.org) * @brief Implementation of cross platform APIs for intrinsic functions (x86 instructions) * @details * @version 0.19 * @date 2026-04-27 * * @copyright This project is released under the GNU Public License v3. * */ #include "pch.h" #if defined(__linux__) # include "../header/PlatformIntrinsics.h" #endif // defined(__linux__) ////////////////////////////////////////////////// // CR Registers // ////////////////////////////////////////////////// /** * @brief Read CR0 * * @return ULONG_PTR */ inline ULONG_PTR CpuReadCr0(VOID) { #if defined(_WIN32) || defined(_WIN64) return __readcr0(); #elif defined(__linux__) ULONG_PTR __val; __asm__ __volatile__("mov %%cr0, %0" : "=r"(__val)); return __val; #else # error "Unsupported platform" #endif } /** * @brief Write CR0 * * @param Cr0Value */ inline VOID CpuWriteCr0(ULONG_PTR Cr0Value) { #if defined(_WIN32) || defined(_WIN64) __writecr0(Cr0Value); #elif defined(__linux__) __asm__ __volatile__("mov %0, %%cr0" : : "r"(Cr0Value) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Read CR2 * * @return ULONG_PTR */ inline ULONG_PTR CpuReadCr2(VOID) { #if defined(_WIN32) || defined(_WIN64) return __readcr2(); #elif defined(__linux__) ULONG_PTR __val; __asm__ __volatile__("mov %%cr2, %0" : "=r"(__val)); return __val; #else # error "Unsupported platform" #endif } /** * @brief Write CR2 * * @param Cr2Value */ inline VOID CpuWriteCr2(ULONG_PTR Cr2Value) { #if defined(_WIN32) || defined(_WIN64) __writecr2(Cr2Value); #elif defined(__linux__) __asm__ __volatile__("mov %0, %%cr2" : : "r"(Cr2Value) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Read CR3 * * @return ULONG_PTR */ inline ULONG_PTR CpuReadCr3(VOID) { #if defined(_WIN32) || defined(_WIN64) return __readcr3(); #elif defined(__linux__) ULONG_PTR __val; __asm__ __volatile__("mov %%cr3, %0" : "=r"(__val)); return __val; #else # error "Unsupported platform" #endif } /** * @brief Write CR3 * * @param Cr3Value */ inline VOID CpuWriteCr3(ULONG_PTR Cr3Value) { #if defined(_WIN32) || defined(_WIN64) __writecr3(Cr3Value); #elif defined(__linux__) __asm__ __volatile__("mov %0, %%cr3" : : "r"(Cr3Value) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Read CR4 * * @return ULONG_PTR */ inline ULONG_PTR CpuReadCr4(VOID) { #if defined(_WIN32) || defined(_WIN64) return __readcr4(); #elif defined(__linux__) ULONG_PTR __val; __asm__ __volatile__("mov %%cr4, %0" : "=r"(__val)); return __val; #else # error "Unsupported platform" #endif } /** * @brief Write CR4 * * @param Cr4Value */ inline VOID CpuWriteCr4(ULONG_PTR Cr4Value) { #if defined(_WIN32) || defined(_WIN64) __writecr4(Cr4Value); #elif defined(__linux__) __asm__ __volatile__("mov %0, %%cr4" : : "r"(Cr4Value) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Read CR8 * * @return ULONG_PTR */ inline ULONG_PTR CpuReadCr8(VOID) { #if defined(_WIN32) || defined(_WIN64) return __readcr8(); #elif defined(__linux__) ULONG_PTR __val; __asm__ __volatile__("mov %%cr8, %0" : "=r"(__val)); return __val; #else # error "Unsupported platform" #endif } /** * @brief Write CR8 * * @param Cr8Value */ inline VOID CpuWriteCr8(ULONG_PTR Cr8Value) { #if defined(_WIN32) || defined(_WIN64) __writecr8(Cr8Value); #elif defined(__linux__) __asm__ __volatile__("mov %0, %%cr8" : : "r"(Cr8Value) : "memory"); #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // MSR Instructions // ////////////////////////////////////////////////// /** * @brief Read an MSR * * @param MsrAddress * @return UINT64 */ inline UINT64 CpuReadMsr(ULONG MsrAddress) { #if defined(_WIN32) || defined(_WIN64) return __readmsr(MsrAddress); #elif defined(__linux__) UINT32 __lo, __hi; __asm__ __volatile__("rdmsr" : "=a"(__lo), "=d"(__hi) : "c"(MsrAddress)); return ((UINT64)__hi << 32) | __lo; #else # error "Unsupported platform" #endif } /** * @brief Write an MSR * * @param MsrAddress * @param MsrValue */ inline VOID CpuWriteMsr(ULONG MsrAddress, UINT64 MsrValue) { #if defined(_WIN32) || defined(_WIN64) __writemsr(MsrAddress, MsrValue); #elif defined(__linux__) __asm__ __volatile__("wrmsr" : : "c"(MsrAddress), "a"((UINT32)MsrValue), "d"((UINT32)(MsrValue >> 32))); #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // CPUID Instructions // ////////////////////////////////////////////////// /** * @brief Execute CPUID * * @param CpuInfo * @param FunctionId */ inline VOID CpuCpuId(INT32 * CpuInfo, INT32 FunctionId) { #if defined(_WIN32) || defined(_WIN64) __cpuid(CpuInfo, FunctionId); #elif defined(__linux__) __asm__ __volatile__("cpuid" : "=a"(CpuInfo[0]), "=b"(CpuInfo[1]), "=c"(CpuInfo[2]), "=d"(CpuInfo[3]) : "a"(FunctionId), "c"(0)); #else # error "Unsupported platform" #endif } /** * @brief Execute CPUID with sub-leaf * * @param CpuInfo * @param FunctionId * @param SubFunctionId */ inline VOID CpuCpuIdEx(INT32 * CpuInfo, INT32 FunctionId, INT32 SubFunctionId) { #if defined(_WIN32) || defined(_WIN64) __cpuidex(CpuInfo, FunctionId, SubFunctionId); #elif defined(__linux__) __asm__ __volatile__("cpuid" : "=a"(CpuInfo[0]), "=b"(CpuInfo[1]), "=c"(CpuInfo[2]), "=d"(CpuInfo[3]) : "a"(FunctionId), "c"(SubFunctionId)); #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // TSC Instructions // ////////////////////////////////////////////////// /** * @brief Read Time-Stamp Counter * * @return UINT64 */ inline UINT64 CpuReadTsc(VOID) { #if defined(_WIN32) || defined(_WIN64) return __rdtsc(); #elif defined(__linux__) UINT32 __lo, __hi; __asm__ __volatile__("rdtsc" : "=a"(__lo), "=d"(__hi)); return ((UINT64)__hi << 32) | __lo; #else # error "Unsupported platform" #endif } /** * @brief Read Time-Stamp Counter and Processor ID * * @param Aux * @return UINT64 */ inline UINT64 CpuReadTscp(UINT32 * Aux) { #if defined(_WIN32) || defined(_WIN64) return __rdtscp(Aux); #elif defined(__linux__) UINT32 __lo, __hi; __asm__ __volatile__("rdtscp" : "=a"(__lo), "=d"(__hi), "=c"(*Aux)); return ((UINT64)__hi << 32) | __lo; #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // Interlocked (Atomic) Operations // ////////////////////////////////////////////////// /** * @brief Atomic 64-bit exchange */ inline INT64 CpuInterlockedExchange64(INT64 volatile * Target, INT64 Value) { #if defined(_WIN32) || defined(_WIN64) return InterlockedExchange64(Target, Value); #elif defined(__linux__) return __atomic_exchange_n(Target, Value, __ATOMIC_SEQ_CST); #else # error "Unsupported platform" #endif } /** * @brief Atomic 64-bit exchange-add */ inline INT64 CpuInterlockedExchangeAdd64(INT64 volatile * Addend, INT64 Value) { #if defined(_WIN32) || defined(_WIN64) return InterlockedExchangeAdd64(Addend, Value); #elif defined(__linux__) return __atomic_fetch_add(Addend, Value, __ATOMIC_SEQ_CST); #else # error "Unsupported platform" #endif } /** * @brief Atomic 64-bit increment */ inline INT64 CpuInterlockedIncrement64(INT64 volatile * Addend) { #if defined(_WIN32) || defined(_WIN64) return InterlockedIncrement64(Addend); #elif defined(__linux__) return __atomic_add_fetch(Addend, 1LL, __ATOMIC_SEQ_CST); #else # error "Unsupported platform" #endif } /** * @brief Atomic 64-bit decrement */ inline INT64 CpuInterlockedDecrement64(INT64 volatile * Addend) { #if defined(_WIN32) || defined(_WIN64) return InterlockedDecrement64(Addend); #elif defined(__linux__) return __atomic_sub_fetch(Addend, 1LL, __ATOMIC_SEQ_CST); #else # error "Unsupported platform" #endif } /** * @brief Atomic 64-bit compare-exchange */ inline INT64 CpuInterlockedCompareExchange64(INT64 volatile * Destination, INT64 ExChange, INT64 Comparand) { #if defined(_WIN32) || defined(_WIN64) return InterlockedCompareExchange64(Destination, ExChange, Comparand); #elif defined(__linux__) INT64 Expected = Comparand; __atomic_compare_exchange_n(Destination, &Expected, ExChange, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); return Expected; #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // Descriptor Table Instructions // ////////////////////////////////////////////////// /** * @brief Store Interrupt Descriptor Table Register * * @param Idtr */ inline VOID CpuSidt(VOID * Idtr) { #if defined(_WIN32) || defined(_WIN64) __sidt(Idtr); #elif defined(__linux__) __asm__ __volatile__("sidt %0" : "=m"(*(char *)Idtr) : : "memory"); #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // TLB Instructions // ////////////////////////////////////////////////// /** * @brief Invalidate TLB entry for a virtual address * * @param Address */ inline VOID CpuInvlpg(VOID * Address) { #if defined(_WIN32) || defined(_WIN64) __invlpg(Address); #elif defined(__linux__) __asm__ __volatile__("invlpg (%0)" : : "r"(Address) : "memory"); #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // String Store Instructions // ////////////////////////////////////////////////// /** * @brief Store UINT64 value to memory Count times * * @param Destination * @param Value * @param Count */ inline VOID CpuStosQ(UINT64 * Destination, UINT64 Value, SIZE_T Count) { #if defined(_WIN32) || defined(_WIN64) __stosq((unsigned __int64 *)Destination, Value, Count); #elif defined(__linux__) __asm__ __volatile__("rep stosq" : "+D"(Destination), "+c"(Count) : "a"(Value) : "memory"); #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // Bit Scan Instructions // ////////////////////////////////////////////////// /** * @brief Bit scan forward (64-bit) * * @param Index * @param Mask * @return UCHAR */ inline UCHAR CpuBitScanForward64(ULONG * Index, UINT64 Mask) { #if defined(_WIN32) || defined(_WIN64) return (UCHAR)_BitScanForward64((unsigned long *)Index, Mask); #elif defined(__linux__) if (!Mask) return 0; *Index = (ULONG)__builtin_ctzll(Mask); return 1; #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // Misc Instructions // ////////////////////////////////////////////////// /** * @brief Execute NOP */ inline VOID CpuNop(VOID) { #if defined(_WIN32) || defined(_WIN64) __nop(); #elif defined(__linux__) __asm__ __volatile__("nop"); #else # error "Unsupported platform" #endif } /** * @brief Execute PAUSE (spin-wait hint) */ inline VOID CpuPause(VOID) { #if defined(_WIN32) || defined(_WIN64) _mm_pause(); #elif defined(__linux__) __asm__ __volatile__("pause"); #else # error "Unsupported platform" #endif } /** * @brief Return the segment limit for a selector * * @param Selector * @return ULONG */ inline ULONG CpuSegmentLimit(UINT32 Selector) { #if defined(_WIN32) || defined(_WIN64) return __segmentlimit(Selector); #elif defined(__linux__) UINT32 Limit; __asm__ __volatile__( "lsl %1, %0" : "=r"(Limit) : "rm"(Selector) : "cc"); return Limit; #else # error "Unsupported platform" #endif } ////////////////////////////////////////////////// // I/O Port Instructions // ////////////////////////////////////////////////// /** * @brief Read a byte from an I/O port * * @param Port * @return UINT8 */ inline UINT8 CpuIoInByte(UINT16 Port) { #if defined(_WIN32) || defined(_WIN64) return __inbyte(Port); #elif defined(__linux__) UINT8 __val; __asm__ __volatile__("inb %1, %0" : "=a"(__val) : "Nd"(Port)); return __val; #else # error "Unsupported platform" #endif } /** * @brief Read a word from an I/O port * * @param Port * @return UINT16 */ inline UINT16 CpuIoInWord(UINT16 Port) { #if defined(_WIN32) || defined(_WIN64) return __inword(Port); #elif defined(__linux__) UINT16 __val; __asm__ __volatile__("inw %1, %0" : "=a"(__val) : "Nd"(Port)); return __val; #else # error "Unsupported platform" #endif } /** * @brief Read a dword from an I/O port * * @param Port * @return UINT32 */ inline UINT32 CpuIoInDword(UINT16 Port) { #if defined(_WIN32) || defined(_WIN64) return __indword(Port); #elif defined(__linux__) UINT32 __val; __asm__ __volatile__("inl %1, %0" : "=a"(__val) : "Nd"(Port)); return __val; #else # error "Unsupported platform" #endif } /** * @brief Read a byte string from an I/O port * * @param Port * @param Data * @param Size */ inline VOID CpuIoInByteString(UINT16 Port, UINT8 * Data, UINT32 Size) { #if defined(_WIN32) || defined(_WIN64) __inbytestring(Port, Data, Size); #elif defined(__linux__) __asm__ __volatile__("rep insb" : "+D"(Data), "+c"(Size) : "d"(Port) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Read a word string from an I/O port * * @param Port * @param Data * @param Size */ inline VOID CpuIoInWordString(UINT16 Port, UINT16 * Data, UINT32 Size) { #if defined(_WIN32) || defined(_WIN64) __inwordstring(Port, Data, Size); #elif defined(__linux__) __asm__ __volatile__("rep insw" : "+D"(Data), "+c"(Size) : "d"(Port) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Read a dword string from an I/O port * * @param Port * @param Data * @param Size */ inline VOID CpuIoInDwordString(UINT16 Port, UINT32 * Data, UINT32 Size) { #if defined(_WIN32) || defined(_WIN64) __indwordstring(Port, (unsigned long *)Data, Size); #elif defined(__linux__) __asm__ __volatile__("rep insl" : "+D"(Data), "+c"(Size) : "d"(Port) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Write a byte to an I/O port * * @param Port * @param Value */ inline VOID CpuIoOutByte(UINT16 Port, UINT8 Value) { #if defined(_WIN32) || defined(_WIN64) __outbyte(Port, Value); #elif defined(__linux__) __asm__ __volatile__("outb %0, %1" : : "a"(Value), "Nd"(Port)); #else # error "Unsupported platform" #endif } /** * @brief Write a word to an I/O port * * @param Port * @param Value */ inline VOID CpuIoOutWord(UINT16 Port, UINT16 Value) { #if defined(_WIN32) || defined(_WIN64) __outword(Port, Value); #elif defined(__linux__) __asm__ __volatile__("outw %0, %1" : : "a"(Value), "Nd"(Port)); #else # error "Unsupported platform" #endif } /** * @brief Write a dword to an I/O port * * @param Port * @param Value */ inline VOID CpuIoOutDword(UINT16 Port, UINT32 Value) { #if defined(_WIN32) || defined(_WIN64) __outdword(Port, Value); #elif defined(__linux__) __asm__ __volatile__("outl %0, %1" : : "a"(Value), "Nd"(Port)); #else # error "Unsupported platform" #endif } /** * @brief Write a byte string to an I/O port * * @param Port * @param Data * @param Count */ inline VOID CpuIoOutByteString(UINT16 Port, UINT8 * Data, UINT32 Count) { #if defined(_WIN32) || defined(_WIN64) __outbytestring(Port, Data, Count); #elif defined(__linux__) __asm__ __volatile__("rep outsb" : "+S"(Data), "+c"(Count) : "d"(Port) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Write a word string to an I/O port * * @param Port * @param Data * @param Count */ inline VOID CpuIoOutWordString(UINT16 Port, UINT16 * Data, UINT32 Count) { #if defined(_WIN32) || defined(_WIN64) __outwordstring(Port, Data, Count); #elif defined(__linux__) __asm__ __volatile__("rep outsw" : "+S"(Data), "+c"(Count) : "d"(Port) : "memory"); #else # error "Unsupported platform" #endif } /** * @brief Write a dword string to an I/O port * * @param Port * @param Data * @param Count */ inline VOID CpuIoOutDwordString(UINT16 Port, UINT32 * Data, UINT32 Count) { #if defined(_WIN32) || defined(_WIN64) __outdwordstring(Port, (unsigned long *)Data, Count); #elif defined(__linux__) __asm__ __volatile__("rep outsl" : "+S"(Data), "+c"(Count) : "d"(Port) : "memory"); #else # error "Unsupported platform" #endif }