mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-10-19 10:04:01 +00:00
Port components/Spinlock.c to Linux kernel module
Route Spinlock.c's three MSVC intrinsics through the platform
intrinsics layer instead of the Windows builtins:
_mm_pause -> CpuPause (already existed)
_interlockedbittestandset -> CpuInterlockedBitTestAndSet (new)
InterlockedCompareExchange-> CpuInterlockedCompareExchange (new, 32-bit)
Add the two new Cpu* wrappers to the kernel PlatformIntrinsics
{.h,.c} with win + linux arms (Linux uses __atomic_* builtins,
mirroring the existing 64-bit CAS), keeping the Cpu* wrappers the
single intrinsic boundary.
This commit is contained in:
parent
368f0302f4
commit
4dc132937f
6 changed files with 77 additions and 11 deletions
|
|
@ -86,12 +86,16 @@ HyperDbg-objs += include/platform/kernel/code/PlatformSpinlock.o
|
|||
HyperDbg-objs += include/platform/kernel/code/PlatformTime.o
|
||||
|
||||
# --- components (shared, header-driven) ------------------------------------
|
||||
# Self-contained (compile clean today):
|
||||
HyperDbg-objs += include/components/spinlock/code/Spinlock.o
|
||||
HyperDbg-objs += include/components/optimizations/code/AvlTree.o
|
||||
HyperDbg-objs += include/components/optimizations/code/BinarySearch.o
|
||||
HyperDbg-objs += include/components/optimizations/code/InsertionSort.o
|
||||
HyperDbg-objs += include/components/optimizations/code/OptimizationsExamples.o
|
||||
HyperDbg-objs += include/components/callback/code/HyperLogCallback.o
|
||||
# hyperlog-gated — these pull in the logging layer (Log/LogInfo) and its globals
|
||||
# (g_Callbacks), so they cannot compile until hyperlog/code/Logging.c is ported.
|
||||
# Uncomment each alongside hyperlog.
|
||||
# HyperDbg-objs += include/components/optimizations/code/BinarySearch.o
|
||||
# HyperDbg-objs += include/components/optimizations/code/OptimizationsExamples.o
|
||||
# HyperDbg-objs += include/components/callback/code/HyperLogCallback.o
|
||||
|
||||
# --- script-eval (script engine kernel eval) -------------------------------
|
||||
# HyperDbg-objs += script-eval/code/Functions.o
|
||||
|
|
@ -101,8 +105,8 @@ HyperDbg-objs += include/components/callback/code/HyperLogCallback.o
|
|||
# HyperDbg-objs += script-eval/code/ScriptEngineEval.o
|
||||
|
||||
# --- hyperlog (message logging/tracing) ------------------------------------
|
||||
# HyperDbg-objs += hyperlog/code/Logging.o
|
||||
# HyperDbg-objs += hyperlog/code/UnloadDll.o
|
||||
HyperDbg-objs += hyperlog/code/Logging.o
|
||||
HyperDbg-objs += hyperlog/code/UnloadDll.o
|
||||
|
||||
# --- hyperhv (hypervisor: VMX/EPT) -----------------------------------------
|
||||
# HyperDbg-objs += hyperhv/code/broadcast/Broadcast.o
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ static UINT32 g_MaxWait = 65536;
|
|||
BOOLEAN
|
||||
SpinlockTryLock(volatile LONG * Lock)
|
||||
{
|
||||
return (!(*Lock) && !_interlockedbittestandset(Lock, 0));
|
||||
return (!(*Lock) && !CpuInterlockedBitTestAndSet(Lock, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -58,7 +58,7 @@ SpinlockLock(volatile LONG * Lock)
|
|||
{
|
||||
for (UINT32 i = 0; i < Wait; ++i)
|
||||
{
|
||||
_mm_pause();
|
||||
CpuPause();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -94,11 +94,11 @@ SpinlockInterlockedCompareExchange(
|
|||
{
|
||||
UINT32 Wait = 1;
|
||||
|
||||
while (InterlockedCompareExchange(Destination, Exchange, Comperand) != Comperand)
|
||||
while (CpuInterlockedCompareExchange(Destination, Exchange, Comperand) != Comperand)
|
||||
{
|
||||
for (UINT32 i = 0; i < Wait; ++i)
|
||||
{
|
||||
_mm_pause();
|
||||
CpuPause();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -133,7 +133,7 @@ SpinlockLockWithCustomWait(volatile LONG * Lock, UINT32 MaximumWait)
|
|||
{
|
||||
for (UINT32 i = 0; i < Wait; ++i)
|
||||
{
|
||||
_mm_pause();
|
||||
CpuPause();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -406,6 +406,40 @@ CpuInterlockedCompareExchange64(INT64 volatile * Destination, INT64 ExChange, IN
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Atomic 32-bit compare-exchange
|
||||
*/
|
||||
inline LONG
|
||||
CpuInterlockedCompareExchange(LONG volatile * Destination, LONG ExChange, LONG Comparand)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
return InterlockedCompareExchange(Destination, ExChange, Comparand);
|
||||
#elif defined(__linux__)
|
||||
LONG Expected = Comparand;
|
||||
__atomic_compare_exchange_n(Destination, &Expected, ExChange, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
||||
return Expected;
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Atomically set a bit, returning its previous value
|
||||
*/
|
||||
inline UCHAR
|
||||
CpuInterlockedBitTestAndSet(volatile LONG * Base, LONG Bit)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
return _interlockedbittestandset(Base, Bit);
|
||||
#elif defined(__linux__)
|
||||
LONG Mask = (1L << Bit);
|
||||
LONG Old = __atomic_fetch_or(Base, Mask, __ATOMIC_SEQ_CST);
|
||||
return (UCHAR)((Old >> Bit) & 1);
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Descriptor Table Instructions //
|
||||
//////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -226,6 +226,12 @@ CpuInterlockedDecrement64(INT64 volatile * Addend);
|
|||
extern inline INT64
|
||||
CpuInterlockedCompareExchange64(INT64 volatile * Destination, INT64 ExChange, INT64 Comparand);
|
||||
|
||||
extern inline LONG
|
||||
CpuInterlockedCompareExchange(LONG volatile * Destination, LONG ExChange, LONG Comparand);
|
||||
|
||||
extern inline UCHAR
|
||||
CpuInterlockedBitTestAndSet(volatile LONG * Base, LONG Bit);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Descriptor Table Instructions //
|
||||
//////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1050,6 +1050,28 @@ them). All three kernel symbols are module-exported (verified). Guard removed.
|
|||
Note: upstream `Logging.c` currently has the timestamp *formatting* commented out
|
||||
(`RtlStringCchPrintfA` not IRQL-safe), so the value is computed but not yet printed.
|
||||
|
||||
### `components/` layer — PARTIAL (2026-08-14)
|
||||
|
||||
Whole `components/` block had been uncommented in `Kbuild` optimistically, but only
|
||||
three of six TUs are self-contained. Active now (compile clean, in `HyperDbg.ko`):
|
||||
`spinlock/Spinlock.o`, `optimizations/AvlTree.o`, `optimizations/InsertionSort.o`.
|
||||
Re-commented (hyperlog-gated — need `Log`/`LogInfo` + the `g_Callbacks` global):
|
||||
`optimizations/BinarySearch.o`, `optimizations/OptimizationsExamples.o`,
|
||||
`callback/HyperLogCallback.o`. Uncomment those alongside `hyperlog/Logging.c`.
|
||||
|
||||
**`Spinlock.c`** — three MSVC intrinsics routed through the platform-intrinsics
|
||||
layer (chosen over file-local shims: keeps the `Cpu*` wrappers the single intrinsic
|
||||
boundary). Two new kernel wrappers added to `PlatformIntrinsics.{h,c}` (both with
|
||||
win + linux arms, mirroring the existing 64-bit CAS):
|
||||
|
||||
| Spinlock.c call | new wrapper | Linux impl |
|
||||
|-----------------|-------------|-----------|
|
||||
| `_mm_pause()` | `CpuPause()` (already existed) | `__asm__("pause")` |
|
||||
| `_interlockedbittestandset(l,0)` | `CpuInterlockedBitTestAndSet` | `__atomic_fetch_or` → old bit |
|
||||
| `InterlockedCompareExchange` | `CpuInterlockedCompareExchange` (32-bit) | `__atomic_compare_exchange_n` |
|
||||
|
||||
`HyperDbg.ko` links clean with these three components active.
|
||||
|
||||
---
|
||||
|
||||
## Building
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit db026cdab3b9d00d2b02691243f215b237792a5b
|
||||
Subproject commit 3fbd59540fd90cda22ad1d00c18129539202070b
|
||||
Loading…
Add table
Add a link
Reference in a new issue