koffi 2.2.3-beta.1 → 2.2.3-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/koffi/build/2.2.3-beta.3/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_win32_x64.tar.gz +0 -0
- package/src/koffi/src/abi_x64_win.cc +28 -23
- package/src/koffi/src/abi_x86.cc +29 -24
- package/src/koffi/src/ffi.cc +86 -36
- package/src/koffi/src/ffi.hh +6 -2
- package/src/koffi/src/win32.hh +59 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_win32_x64.tar.gz +0 -0
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -17,14 +17,7 @@
|
|
|
17
17
|
#include "ffi.hh"
|
|
18
18
|
#include "call.hh"
|
|
19
19
|
#include "util.hh"
|
|
20
|
-
|
|
21
|
-
#ifndef NOMINMAX
|
|
22
|
-
#define NOMINMAX
|
|
23
|
-
#endif
|
|
24
|
-
#ifndef WIN32_LEAN_AND_MEAN
|
|
25
|
-
#define WIN32_LEAN_AND_MEAN
|
|
26
|
-
#endif
|
|
27
|
-
#include <windows.h>
|
|
20
|
+
#include "win32.hh"
|
|
28
21
|
|
|
29
22
|
#include <napi.h>
|
|
30
23
|
|
|
@@ -224,15 +217,21 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
224
217
|
|
|
225
218
|
void CallData::Execute(const FunctionInfo *func)
|
|
226
219
|
{
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
//
|
|
230
|
-
RG_DEFER_C(base =
|
|
231
|
-
|
|
232
|
-
|
|
220
|
+
TEB *teb = GetTEB();
|
|
221
|
+
|
|
222
|
+
// Restore previous stack limits at the end
|
|
223
|
+
RG_DEFER_C(base = teb->StackBase,
|
|
224
|
+
limit = teb->StackLimit,
|
|
225
|
+
dealloc = teb->DeallocationStack) {
|
|
226
|
+
teb->StackBase = base;
|
|
227
|
+
teb->StackLimit = limit;
|
|
228
|
+
teb->DeallocationStack = dealloc;
|
|
233
229
|
};
|
|
234
|
-
|
|
235
|
-
|
|
230
|
+
|
|
231
|
+
// Adjust stack limits so SEH works correctly
|
|
232
|
+
teb->StackBase = mem->stack0.end();
|
|
233
|
+
teb->StackLimit = mem->stack0.ptr;
|
|
234
|
+
teb->DeallocationStack = mem->stack0.ptr;
|
|
236
235
|
|
|
237
236
|
#define PERFORM_CALL(Suffix) \
|
|
238
237
|
([&]() { \
|
|
@@ -335,15 +334,21 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
335
334
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
336
335
|
return;
|
|
337
336
|
|
|
338
|
-
|
|
337
|
+
TEB *teb = GetTEB();
|
|
339
338
|
|
|
340
|
-
// Restore
|
|
341
|
-
RG_DEFER_C(base =
|
|
342
|
-
|
|
343
|
-
|
|
339
|
+
// Restore previous stack limits at the end
|
|
340
|
+
RG_DEFER_C(base = teb->StackBase,
|
|
341
|
+
limit = teb->StackLimit,
|
|
342
|
+
dealloc = teb->DeallocationStack) {
|
|
343
|
+
teb->StackBase = base;
|
|
344
|
+
teb->StackLimit = limit;
|
|
345
|
+
teb->DeallocationStack = dealloc;
|
|
344
346
|
};
|
|
345
|
-
|
|
346
|
-
|
|
347
|
+
|
|
348
|
+
// Adjust stack limits so SEH works correctly
|
|
349
|
+
teb->StackBase = instance->main_stack_max;
|
|
350
|
+
teb->StackLimit = instance->main_stack_min;
|
|
351
|
+
teb->DeallocationStack = instance->main_stack_min;
|
|
347
352
|
|
|
348
353
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
349
354
|
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -17,15 +17,8 @@
|
|
|
17
17
|
#include "ffi.hh"
|
|
18
18
|
#include "call.hh"
|
|
19
19
|
#include "util.hh"
|
|
20
|
-
|
|
21
20
|
#ifdef _WIN32
|
|
22
|
-
#
|
|
23
|
-
#define NOMINMAX
|
|
24
|
-
#endif
|
|
25
|
-
#ifndef WIN32_LEAN_AND_MEAN
|
|
26
|
-
#define WIN32_LEAN_AND_MEAN
|
|
27
|
-
#endif
|
|
28
|
-
#include <windows.h>
|
|
21
|
+
#include "win32.hh"
|
|
29
22
|
#endif
|
|
30
23
|
|
|
31
24
|
#include <napi.h>
|
|
@@ -308,15 +301,21 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
308
301
|
void CallData::Execute(const FunctionInfo *func)
|
|
309
302
|
{
|
|
310
303
|
#ifdef _WIN32
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
//
|
|
314
|
-
RG_DEFER_C(base =
|
|
315
|
-
|
|
316
|
-
|
|
304
|
+
TEB *teb = GetTEB();
|
|
305
|
+
|
|
306
|
+
// Restore previous stack limits at the end
|
|
307
|
+
RG_DEFER_C(base = teb->StackBase,
|
|
308
|
+
limit = teb->StackLimit,
|
|
309
|
+
dealloc = teb->DeallocationStack) {
|
|
310
|
+
teb->StackBase = base;
|
|
311
|
+
teb->StackLimit = limit;
|
|
312
|
+
teb->DeallocationStack = dealloc;
|
|
317
313
|
};
|
|
318
|
-
|
|
319
|
-
|
|
314
|
+
|
|
315
|
+
// Adjust stack limits so SEH works correctly
|
|
316
|
+
teb->StackBase = mem->stack0.end();
|
|
317
|
+
teb->StackLimit = mem->stack0.ptr;
|
|
318
|
+
teb->DeallocationStack = mem->stack0.ptr;
|
|
320
319
|
#endif
|
|
321
320
|
|
|
322
321
|
#define PERFORM_CALL(Suffix) \
|
|
@@ -422,15 +421,21 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
422
421
|
return;
|
|
423
422
|
|
|
424
423
|
#ifdef _WIN32
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
// Restore
|
|
428
|
-
RG_DEFER_C(base =
|
|
429
|
-
|
|
430
|
-
|
|
424
|
+
TEB *teb = GetTEB();
|
|
425
|
+
|
|
426
|
+
// Restore previous stack limits at the end
|
|
427
|
+
RG_DEFER_C(base = teb->StackBase,
|
|
428
|
+
limit = teb->StackLimit,
|
|
429
|
+
dealloc = teb->DeallocationStack) {
|
|
430
|
+
teb->StackBase = base;
|
|
431
|
+
teb->StackLimit = limit;
|
|
432
|
+
teb->DeallocationStack = dealloc;
|
|
431
433
|
};
|
|
432
|
-
|
|
433
|
-
|
|
434
|
+
|
|
435
|
+
// Adjust stack limits so SEH works correctly
|
|
436
|
+
teb->StackBase = instance->main_stack_max;
|
|
437
|
+
teb->StackLimit = instance->main_stack_min;
|
|
438
|
+
teb->DeallocationStack = instance->main_stack_min;
|
|
434
439
|
#endif
|
|
435
440
|
|
|
436
441
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
#include "call.hh"
|
|
17
17
|
#include "parser.hh"
|
|
18
18
|
#include "util.hh"
|
|
19
|
+
#ifdef _WIN32
|
|
20
|
+
#include "win32.hh"
|
|
21
|
+
#endif
|
|
19
22
|
|
|
20
23
|
#ifdef _WIN32
|
|
21
24
|
#ifndef NOMINMAX
|
|
@@ -1014,13 +1017,59 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1014
1017
|
return nullptr;
|
|
1015
1018
|
|
|
1016
1019
|
InstanceMemory *mem = new InstanceMemory();
|
|
1020
|
+
RG_DEFER_N(mem_guard) { delete mem; };
|
|
1017
1021
|
|
|
1018
|
-
mem->stack.len = stack_size;
|
|
1019
1022
|
#if defined(_WIN32)
|
|
1020
|
-
|
|
1023
|
+
{
|
|
1024
|
+
struct FiberContext {
|
|
1025
|
+
InstanceMemory *mem;
|
|
1026
|
+
void *self;
|
|
1027
|
+
bool was_fiber;
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
FiberContext ctx;
|
|
1031
|
+
bool is_fiber = IsThreadAFiber();
|
|
1032
|
+
|
|
1033
|
+
ctx.mem = mem;
|
|
1034
|
+
ctx.self = is_fiber ? GetCurrentFiber() : ConvertThreadToFiber(nullptr);
|
|
1035
|
+
if (!ctx.self) {
|
|
1036
|
+
LogError("Failed to make initial fiber: %1", GetWin32ErrorString());
|
|
1037
|
+
return nullptr;
|
|
1038
|
+
}
|
|
1039
|
+
RG_DEFER {
|
|
1040
|
+
if (!is_fiber) {
|
|
1041
|
+
ConvertFiberToThread();
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
|
|
1045
|
+
// Work around issue with CreateFiber() API and stack size
|
|
1046
|
+
// See here: https://github.com/google/marl/issues/12
|
|
1047
|
+
mem->fiber = CreateFiberEx(stack_size - 1, stack_size,
|
|
1048
|
+
FIBER_FLAG_FLOAT_SWITCH, [](void *udata) {
|
|
1049
|
+
FiberContext *ctx = (FiberContext *)udata;
|
|
1050
|
+
|
|
1051
|
+
TEB *teb = GetTEB();
|
|
1052
|
+
|
|
1053
|
+
ctx->mem->stack.ptr = (uint8_t *)teb->DeallocationStack;
|
|
1054
|
+
ctx->mem->stack.len = (uint8_t *)teb->StackBase - ctx->mem->stack.ptr;
|
|
1055
|
+
|
|
1056
|
+
SwitchToFiber(ctx->self);
|
|
1057
|
+
}, &ctx);
|
|
1058
|
+
|
|
1059
|
+
if (!mem->fiber) {
|
|
1060
|
+
LogError("Failed to create Win32 fiber: %1", GetWin32ErrorString());
|
|
1061
|
+
return nullptr;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
SwitchToFiber(mem->fiber);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
RG_ASSERT(mem->stack.ptr);
|
|
1021
1068
|
#elif defined(__APPLE__)
|
|
1069
|
+
mem->stack.len = stack_size;
|
|
1022
1070
|
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
1023
1071
|
#else
|
|
1072
|
+
mem->stack.len = stack_size;
|
|
1024
1073
|
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
|
|
1025
1074
|
#endif
|
|
1026
1075
|
RG_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
@@ -1051,6 +1100,7 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1051
1100
|
mem->temporary = true;
|
|
1052
1101
|
}
|
|
1053
1102
|
|
|
1103
|
+
mem_guard.Disable();
|
|
1054
1104
|
return mem;
|
|
1055
1105
|
}
|
|
1056
1106
|
|
|
@@ -1691,8 +1741,8 @@ void FunctionInfo::Unref() const
|
|
|
1691
1741
|
InstanceMemory::~InstanceMemory()
|
|
1692
1742
|
{
|
|
1693
1743
|
#ifdef _WIN32
|
|
1694
|
-
if (
|
|
1695
|
-
|
|
1744
|
+
if (fiber) {
|
|
1745
|
+
DeleteFiber(fiber);
|
|
1696
1746
|
}
|
|
1697
1747
|
if (heap.ptr) {
|
|
1698
1748
|
VirtualFree(heap.ptr, 0, MEM_RELEASE);
|
|
@@ -1707,6 +1757,38 @@ InstanceMemory::~InstanceMemory()
|
|
|
1707
1757
|
#endif
|
|
1708
1758
|
}
|
|
1709
1759
|
|
|
1760
|
+
static InstanceData *CreateInstance(Napi::Env env)
|
|
1761
|
+
{
|
|
1762
|
+
InstanceData *instance = new InstanceData();
|
|
1763
|
+
RG_DEFER_N(err_guard) { delete instance; };
|
|
1764
|
+
|
|
1765
|
+
instance->main_thread_id = std::this_thread::get_id();
|
|
1766
|
+
|
|
1767
|
+
if (napi_create_threadsafe_function(env, nullptr, nullptr,
|
|
1768
|
+
Napi::String::New(env, "Koffi Async Callback Broker"),
|
|
1769
|
+
0, 1, nullptr, nullptr, nullptr,
|
|
1770
|
+
CallData::RelayAsync, &instance->broker) != napi_ok) {
|
|
1771
|
+
LogError("Failed to create async callback broker");
|
|
1772
|
+
return nullptr;
|
|
1773
|
+
}
|
|
1774
|
+
napi_unref_threadsafe_function(env, instance->broker);
|
|
1775
|
+
|
|
1776
|
+
#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
|
|
1777
|
+
void *teb = (void *)__readgsqword(0x30);
|
|
1778
|
+
|
|
1779
|
+
instance->main_stack_max = *(void **)((uint8_t *)teb + 0x08); // StackBase
|
|
1780
|
+
instance->main_stack_min = *(void **)((uint8_t *)teb + 0x1478); // DeallocationStack
|
|
1781
|
+
#elif defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
|
|
1782
|
+
void *teb = (void *)__readfsdword(0x18);
|
|
1783
|
+
|
|
1784
|
+
instance->main_stack_max = *(void **)((uint8_t *)teb + 0x04); // StackBase
|
|
1785
|
+
instance->main_stack_min = *(void **)((uint8_t *)teb + 0xE0C); // DeallocationStack
|
|
1786
|
+
#endif
|
|
1787
|
+
|
|
1788
|
+
err_guard.Disable();
|
|
1789
|
+
return instance;
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1710
1792
|
InstanceData::~InstanceData()
|
|
1711
1793
|
{
|
|
1712
1794
|
for (InstanceMemory *mem: memories) {
|
|
@@ -1916,38 +1998,6 @@ extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, Bac
|
|
|
1916
1998
|
}
|
|
1917
1999
|
}
|
|
1918
2000
|
|
|
1919
|
-
static InstanceData *CreateInstance(Napi::Env env)
|
|
1920
|
-
{
|
|
1921
|
-
InstanceData *instance = new InstanceData();
|
|
1922
|
-
RG_DEFER_N(err_guard) { delete instance; };
|
|
1923
|
-
|
|
1924
|
-
instance->main_thread_id = std::this_thread::get_id();
|
|
1925
|
-
|
|
1926
|
-
if (napi_create_threadsafe_function(env, nullptr, nullptr,
|
|
1927
|
-
Napi::String::New(env, "Koffi Async Callback Broker"),
|
|
1928
|
-
0, 1, nullptr, nullptr, nullptr,
|
|
1929
|
-
CallData::RelayAsync, &instance->broker) != napi_ok) {
|
|
1930
|
-
LogError("Failed to create async callback broker");
|
|
1931
|
-
return nullptr;
|
|
1932
|
-
}
|
|
1933
|
-
napi_unref_threadsafe_function(env, instance->broker);
|
|
1934
|
-
|
|
1935
|
-
#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
|
|
1936
|
-
NT_TIB *tib = (NT_TIB *)__readgsqword(0x30);
|
|
1937
|
-
|
|
1938
|
-
instance->main_stack_base = tib->StackBase;
|
|
1939
|
-
instance->main_stack_limit = tib->StackLimit;
|
|
1940
|
-
#elif defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
|
|
1941
|
-
NT_TIB *tib = (NT_TIB *)__readfsdword(0x18);
|
|
1942
|
-
|
|
1943
|
-
instance->main_stack_base = tib->StackBase;
|
|
1944
|
-
instance->main_stack_limit = tib->StackLimit;
|
|
1945
|
-
#endif
|
|
1946
|
-
|
|
1947
|
-
err_guard.Disable();
|
|
1948
|
-
return instance;
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1951
2001
|
template <typename Func>
|
|
1952
2002
|
static void SetExports(Napi::Env env, Func func)
|
|
1953
2003
|
{
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -232,6 +232,10 @@ struct InstanceMemory {
|
|
|
232
232
|
|
|
233
233
|
int16_t depth;
|
|
234
234
|
bool temporary;
|
|
235
|
+
|
|
236
|
+
#ifdef _WIN32
|
|
237
|
+
void *fiber;
|
|
238
|
+
#endif
|
|
235
239
|
};
|
|
236
240
|
|
|
237
241
|
struct InstanceData {
|
|
@@ -256,8 +260,8 @@ struct InstanceData {
|
|
|
256
260
|
napi_threadsafe_function broker = nullptr;
|
|
257
261
|
|
|
258
262
|
#ifdef _WIN32
|
|
259
|
-
void *
|
|
260
|
-
void *
|
|
263
|
+
void *main_stack_max;
|
|
264
|
+
void *main_stack_min;
|
|
261
265
|
#endif
|
|
262
266
|
|
|
263
267
|
HashMap<void *, int16_t> trampolines_map;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// This program is free software: you can redistribute it and/or modify
|
|
2
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
3
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
// (at your option) any later version.
|
|
5
|
+
//
|
|
6
|
+
// This program is distributed in the hope that it will be useful,
|
|
7
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
// GNU Affero General Public License for more details.
|
|
10
|
+
//
|
|
11
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
12
|
+
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
|
+
|
|
14
|
+
#pragma once
|
|
15
|
+
|
|
16
|
+
#include "src/core/libcc/libcc.hh"
|
|
17
|
+
|
|
18
|
+
#include <intrin.h>
|
|
19
|
+
|
|
20
|
+
namespace RG {
|
|
21
|
+
|
|
22
|
+
#if _WIN64
|
|
23
|
+
|
|
24
|
+
struct TEB {
|
|
25
|
+
char _pad1[8];
|
|
26
|
+
void *StackBase;
|
|
27
|
+
void *StackLimit;
|
|
28
|
+
char _pad2[5216];
|
|
29
|
+
void *DeallocationStack;
|
|
30
|
+
};
|
|
31
|
+
RG_STATIC_ASSERT(RG_OFFSET_OF(TEB, DeallocationStack) == 0x1478);
|
|
32
|
+
|
|
33
|
+
#else
|
|
34
|
+
|
|
35
|
+
struct TEB {
|
|
36
|
+
char _pad1[4];
|
|
37
|
+
void *StackBase;
|
|
38
|
+
void *StackLimit;
|
|
39
|
+
char _pad2[3584];
|
|
40
|
+
void *DeallocationStack;
|
|
41
|
+
};
|
|
42
|
+
RG_STATIC_ASSERT(RG_OFFSET_OF(TEB, DeallocationStack) == 0xE0C);
|
|
43
|
+
|
|
44
|
+
#endif
|
|
45
|
+
|
|
46
|
+
static inline TEB *GetTEB()
|
|
47
|
+
{
|
|
48
|
+
#if defined(__aarch64__) || defined(_M_ARM64)
|
|
49
|
+
TEB *teb = (TEB *)__getReg(18);
|
|
50
|
+
#elif defined(__x86_64__) || defined(_M_AMD64)
|
|
51
|
+
TEB *teb = (TEB *)__readgsqword(0x30);
|
|
52
|
+
#else
|
|
53
|
+
TEB *teb = (TEB *)__readfsdword(0x18);
|
|
54
|
+
#endif
|
|
55
|
+
|
|
56
|
+
return teb;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|