mirror of
https://github.com/rehlds/reapi.git
synced 2024-12-27 07:05:28 +03:00
Fix SetHookChainArg crash due to incorrect pointer to argument (hookctx_t gets the original function as the base address of the arguments, some compilers do UB and so for this reason hookctx_t has been reworked and now uses tuple).
Update reapi.inc - added ATYPE_BOOL and ATYPE_EVARS types Compiler: added option flag -static-libstdc++
This commit is contained in:
parent
0a17573bed
commit
8b26f29d54
@ -57,7 +57,7 @@ void setupToolchain(NativeBinarySpec b) {
|
|||||||
pchSourceSet: 'reapi_pch'
|
pchSourceSet: 'reapi_pch'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
cfg.compilerOptions.languageStandard = 'c++11'
|
cfg.compilerOptions.languageStandard = 'c++14'
|
||||||
cfg.defines([
|
cfg.defines([
|
||||||
'_stricmp': 'strcasecmp',
|
'_stricmp': 'strcasecmp',
|
||||||
'_strnicmp': 'strncasecmp',
|
'_strnicmp': 'strncasecmp',
|
||||||
@ -71,6 +71,9 @@ void setupToolchain(NativeBinarySpec b) {
|
|||||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-inline-forceinline', '-no-ansi-alias'
|
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-inline-forceinline', '-no-ansi-alias'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg.linkerOptions.args '-Wl,--version-script=../version_script.lds', '-Wl,--gc-sections'
|
||||||
|
cfg.compilerOptions.args '-ffunction-sections', '-fdata-sections' // Remove unused code and data
|
||||||
|
|
||||||
cfg.compilerOptions.args '-Wall', '-Wno-unknown-pragmas', '-msse2', '-fomit-frame-pointer', '-fvisibility=default', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s', '-fno-exceptions'
|
cfg.compilerOptions.args '-Wall', '-Wno-unknown-pragmas', '-msse2', '-fomit-frame-pointer', '-fvisibility=default', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s', '-fno-exceptions'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,9 @@ enum AType
|
|||||||
ATYPE_FLOAT,
|
ATYPE_FLOAT,
|
||||||
ATYPE_STRING,
|
ATYPE_STRING,
|
||||||
ATYPE_CLASSPTR,
|
ATYPE_CLASSPTR,
|
||||||
ATYPE_EDICT
|
ATYPE_EDICT,
|
||||||
|
ATYPE_EVARS,
|
||||||
|
ATYPE_BOOL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HookChain
|
enum HookChain
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
// hookchain return type
|
// hookchain return type
|
||||||
enum HookChainState
|
enum HookChainState
|
||||||
{
|
{
|
||||||
@ -17,7 +19,8 @@ enum AType : uint8
|
|||||||
ATYPE_STRING,
|
ATYPE_STRING,
|
||||||
ATYPE_CLASSPTR,
|
ATYPE_CLASSPTR,
|
||||||
ATYPE_EDICT,
|
ATYPE_EDICT,
|
||||||
ATYPE_EVARS
|
ATYPE_EVARS,
|
||||||
|
ATYPE_BOOL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct retval_t
|
struct retval_t
|
||||||
@ -44,6 +47,7 @@ inline AType getApiType(char[]) { return ATYPE_STRING; }
|
|||||||
inline AType getApiType(CBaseEntity *) { return ATYPE_CLASSPTR; }
|
inline AType getApiType(CBaseEntity *) { return ATYPE_CLASSPTR; }
|
||||||
inline AType getApiType(edict_t *) { return ATYPE_EDICT; }
|
inline AType getApiType(edict_t *) { return ATYPE_EDICT; }
|
||||||
inline AType getApiType(entvars_t *) { return ATYPE_EVARS; }
|
inline AType getApiType(entvars_t *) { return ATYPE_EVARS; }
|
||||||
|
inline AType getApiType(bool) { return ATYPE_BOOL; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline AType getApiType(T *) { return ATYPE_INTEGER; }
|
inline AType getApiType(T *) { return ATYPE_INTEGER; }
|
||||||
@ -63,64 +67,47 @@ bool hasStringArgs(T, f_args... args)
|
|||||||
|
|
||||||
#define MAX_HOOKCHAIN_ARGS 12u
|
#define MAX_HOOKCHAIN_ARGS 12u
|
||||||
|
|
||||||
template<size_t current = 0, typename T1, typename T2, typename T3, typename T4, typename ...t_args>
|
|
||||||
void setupArgTypes(AType args_type[], T1, T2, T3, T4, t_args... args)
|
|
||||||
{
|
|
||||||
if (current + 4 <= MAX_HOOKCHAIN_ARGS)
|
|
||||||
*(uint32 *)&args_type[current] = getApiType(T1()) | (getApiType(T2()) << 8) | (getApiType(T3()) << 16) | (getApiType(T4()) << 24);
|
|
||||||
if (sizeof...(args) && current + 4 < MAX_HOOKCHAIN_ARGS)
|
|
||||||
setupArgTypes<current + 4>(args_type, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t current = 0, typename T1, typename T2, typename T3>
|
|
||||||
void setupArgTypes(AType args_type[], T1, T2, T3)
|
|
||||||
{
|
|
||||||
if (current + 3 <= MAX_HOOKCHAIN_ARGS)
|
|
||||||
*(uint32 *)&args_type[current] = getApiType(T1()) | (getApiType(T2()) << 8) | (getApiType(T3()) << 16);
|
|
||||||
else
|
|
||||||
setupArgTypes(args_type, T1(), T2());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t current = 0, typename T1, typename T2>
|
|
||||||
void setupArgTypes(AType args_type[], T1, T2)
|
|
||||||
{
|
|
||||||
if (current + 2 <= MAX_HOOKCHAIN_ARGS)
|
|
||||||
*(uint16 *)&args_type[current] = getApiType(T1()) | (getApiType(T2()) << 8);
|
|
||||||
else
|
|
||||||
setupArgTypes(args_type, T1());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t current = 0, typename T>
|
|
||||||
void setupArgTypes(AType args_type[], T)
|
|
||||||
{
|
|
||||||
if (current + 1 <= MAX_HOOKCHAIN_ARGS)
|
|
||||||
args_type[current] = getApiType(T());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t current = 0>
|
|
||||||
void setupArgTypes(AType args_type[])
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
struct hookctx_t
|
struct hookctx_t
|
||||||
{
|
{
|
||||||
template<typename ...t_args>
|
template<typename ...t_args>
|
||||||
hookctx_t(size_t arg_count, t_args... args)
|
hookctx_t(size_t arg_count, t_args&&... args)
|
||||||
{
|
{
|
||||||
args_count = min(arg_count, MAX_HOOKCHAIN_ARGS);
|
|
||||||
|
|
||||||
if (hasStringArgs(args...)) {
|
if (hasStringArgs(args...)) {
|
||||||
tempstrings_used = 0;
|
tempstrings_used = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
setupArgTypes(args_type, args...);
|
args_count = min(arg_count, MAX_HOOKCHAIN_ARGS);
|
||||||
|
setArgs(std::forward_as_tuple(args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(size_t arg_ptr, AType ret_type = ATYPE_INTEGER)
|
template <size_t current = 0,
|
||||||
|
typename tuple_t,
|
||||||
|
size_t size = std::tuple_size<typename std::decay<tuple_t>::type>::value,
|
||||||
|
std::enable_if_t<current >= size>* = nullptr> // if current >= size
|
||||||
|
void setArgs(tuple_t &&t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t current = 0,
|
||||||
|
typename tuple_t,
|
||||||
|
size_t size = std::tuple_size<typename std::decay<tuple_t>::type>::value,
|
||||||
|
std::enable_if_t<current < size>* = nullptr> // if current < size
|
||||||
|
void setArgs(tuple_t &&t)
|
||||||
|
{
|
||||||
|
// current iteration
|
||||||
|
if (current < MAX_HOOKCHAIN_ARGS)
|
||||||
|
{
|
||||||
|
auto &arg = std::get<current>(std::forward<tuple_t>(t));
|
||||||
|
args[current].handle = (size_t)&arg;
|
||||||
|
args[current].type = getApiType(arg);
|
||||||
|
setArgs<current + 1>(std::forward<tuple_t>(t)); // call next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(AType ret_type = ATYPE_INTEGER)
|
||||||
{
|
{
|
||||||
retVal.set = false;
|
retVal.set = false;
|
||||||
retVal.type = ret_type;
|
retVal.type = ret_type;
|
||||||
args_ptr = arg_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* get_temp_string(AMX* amx)
|
char* get_temp_string(AMX* amx)
|
||||||
@ -140,29 +127,34 @@ struct hookctx_t
|
|||||||
s_temp_strings.pop(tempstrings_used);
|
s_temp_strings.pop(tempstrings_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval_t retVal;
|
retval_t retVal = {false,ATYPE_INTEGER};
|
||||||
size_t args_count;
|
size_t tempstrings_used = 0;
|
||||||
size_t args_ptr;
|
|
||||||
size_t tempstrings_used;
|
|
||||||
AType args_type[MAX_HOOKCHAIN_ARGS];
|
|
||||||
|
|
||||||
|
struct args_t
|
||||||
|
{
|
||||||
|
size_t handle;
|
||||||
|
AType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t args_count = 0;
|
||||||
|
args_t args[MAX_HOOKCHAIN_ARGS] = {0u, ATYPE_INTEGER};
|
||||||
static CTempStrings s_temp_strings;
|
static CTempStrings s_temp_strings;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern hookctx_t* g_hookCtx;
|
extern hookctx_t* g_hookCtx;
|
||||||
|
|
||||||
template <typename original_t, typename ...f_args>
|
template <typename original_t, typename ...f_args>
|
||||||
NOINLINE void DLLEXPORT _callVoidForward(const hook_t* hook, original_t original, volatile f_args... args)
|
NOINLINE void DLLEXPORT _callVoidForward(const hook_t* hook, original_t original, f_args&&... args)
|
||||||
{
|
{
|
||||||
auto hookCtx = g_hookCtx;
|
auto hookCtx = g_hookCtx;
|
||||||
hookCtx->reset(size_t(&original) + sizeof(original));
|
hookCtx->reset();
|
||||||
int hc_state = HC_CONTINUE;
|
int hc_state = HC_CONTINUE;
|
||||||
|
|
||||||
for (auto fwd : hook->pre)
|
for (auto fwd : hook->pre)
|
||||||
{
|
{
|
||||||
if (likely(fwd->GetState() == FSTATE_ENABLED))
|
if (likely(fwd->GetState() == FSTATE_ENABLED))
|
||||||
{
|
{
|
||||||
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), args...);
|
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward<f_args &&>(args)...);
|
||||||
|
|
||||||
if (unlikely(ret == HC_BREAK)) {
|
if (unlikely(ret == HC_BREAK)) {
|
||||||
return;
|
return;
|
||||||
@ -175,13 +167,13 @@ NOINLINE void DLLEXPORT _callVoidForward(const hook_t* hook, original_t original
|
|||||||
|
|
||||||
if (hc_state != HC_SUPERCEDE) {
|
if (hc_state != HC_SUPERCEDE) {
|
||||||
g_hookCtx = nullptr;
|
g_hookCtx = nullptr;
|
||||||
original(args...);
|
original(std::forward<f_args &&>(args)...);
|
||||||
g_hookCtx = hookCtx;
|
g_hookCtx = hookCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto fwd : hook->post) {
|
for (auto fwd : hook->post) {
|
||||||
if (likely(fwd->GetState() == FSTATE_ENABLED)) {
|
if (likely(fwd->GetState() == FSTATE_ENABLED)) {
|
||||||
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), args...);
|
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward<f_args &&>(args)...);
|
||||||
|
|
||||||
if (unlikely(ret == HC_BREAK))
|
if (unlikely(ret == HC_BREAK))
|
||||||
break;
|
break;
|
||||||
@ -190,7 +182,7 @@ NOINLINE void DLLEXPORT _callVoidForward(const hook_t* hook, original_t original
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename original_t, typename ...f_args>
|
template <typename original_t, typename ...f_args>
|
||||||
void callVoidForward(size_t func, original_t original, f_args... args)
|
void callVoidForward(size_t func, original_t original, f_args&&... args)
|
||||||
{
|
{
|
||||||
hookctx_t hookCtx(sizeof...(args), args...);
|
hookctx_t hookCtx(sizeof...(args), args...);
|
||||||
hookctx_t* save = g_hookCtx;
|
hookctx_t* save = g_hookCtx;
|
||||||
@ -205,17 +197,18 @@ void callVoidForward(size_t func, original_t original, f_args... args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename original_t, typename ...f_args>
|
template <typename R, typename original_t, typename ...f_args>
|
||||||
NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, volatile f_args... args)
|
NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, f_args&&... args)
|
||||||
{
|
{
|
||||||
auto hookCtx = g_hookCtx;
|
auto hookCtx = g_hookCtx;
|
||||||
hookCtx->reset(size_t(&original) + sizeof(original), getApiType(R()));
|
hookCtx->reset(getApiType(R()));
|
||||||
|
|
||||||
int hc_state = HC_CONTINUE;
|
int hc_state = HC_CONTINUE;
|
||||||
|
|
||||||
for (auto fwd : hook->pre)
|
for (auto fwd : hook->pre)
|
||||||
{
|
{
|
||||||
if (likely(fwd->GetState() == FSTATE_ENABLED))
|
if (likely(fwd->GetState() == FSTATE_ENABLED))
|
||||||
{
|
{
|
||||||
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), args...);
|
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward<f_args &&>(args)...);
|
||||||
|
|
||||||
if (likely(ret == HC_CONTINUE)) {
|
if (likely(ret == HC_CONTINUE)) {
|
||||||
continue;
|
continue;
|
||||||
@ -238,7 +231,7 @@ NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, volat
|
|||||||
if (likely(hc_state != HC_SUPERCEDE))
|
if (likely(hc_state != HC_SUPERCEDE))
|
||||||
{
|
{
|
||||||
g_hookCtx = nullptr;
|
g_hookCtx = nullptr;
|
||||||
auto retVal = original(args...);
|
auto retVal = original(std::forward<f_args &&>(args)...);
|
||||||
g_hookCtx = hookCtx;
|
g_hookCtx = hookCtx;
|
||||||
|
|
||||||
if (unlikely(!hookCtx->retVal.set)) {
|
if (unlikely(!hookCtx->retVal.set)) {
|
||||||
@ -259,7 +252,7 @@ NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, volat
|
|||||||
|
|
||||||
for (auto fwd : hook->post) {
|
for (auto fwd : hook->post) {
|
||||||
if (likely(fwd->GetState() == FSTATE_ENABLED)) {
|
if (likely(fwd->GetState() == FSTATE_ENABLED)) {
|
||||||
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), args...);
|
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward<f_args &&>(args)...);
|
||||||
|
|
||||||
if (unlikely(ret == HC_BREAK))
|
if (unlikely(ret == HC_BREAK))
|
||||||
break;
|
break;
|
||||||
@ -270,7 +263,7 @@ NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, volat
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename original_t, typename ...f_args>
|
template <typename R, typename original_t, typename ...f_args>
|
||||||
R callForward(size_t func, original_t original, f_args... args)
|
R callForward(size_t func, original_t original, f_args&&... args)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(R) <= sizeof(int), "invalid hookchain return type size > sizeof(int)");
|
static_assert(sizeof(R) <= sizeof(int), "invalid hookchain return type size > sizeof(int)");
|
||||||
|
|
||||||
|
@ -255,8 +255,7 @@ cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
AType type = g_hookCtx->args_type[number];
|
AType type = g_hookCtx->args[number].type;
|
||||||
|
|
||||||
if (unlikely(params[arg_type] != type))
|
if (unlikely(params[arg_type] != type))
|
||||||
{
|
{
|
||||||
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: invalid argument type provided.", __FUNCTION__);
|
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: invalid argument type provided.", __FUNCTION__);
|
||||||
@ -264,7 +263,7 @@ cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
|
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
|
||||||
size_t destAddr = g_hookCtx->args_ptr + number * sizeof(int);
|
size_t destAddr = g_hookCtx->args[number].handle;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -272,6 +271,9 @@ cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
|||||||
case ATYPE_FLOAT:
|
case ATYPE_FLOAT:
|
||||||
*(cell *)destAddr = *srcAddr;
|
*(cell *)destAddr = *srcAddr;
|
||||||
break;
|
break;
|
||||||
|
case ATYPE_BOOL:
|
||||||
|
*(bool *)destAddr = *srcAddr != 0;
|
||||||
|
break;
|
||||||
case ATYPE_STRING:
|
case ATYPE_STRING:
|
||||||
*(char **)destAddr = getAmxString(srcAddr, g_hookCtx->get_temp_string(amx), CTempStrings::STRING_LEN);
|
*(char **)destAddr = getAmxString(srcAddr, g_hookCtx->get_temp_string(amx), CTempStrings::STRING_LEN);
|
||||||
break;
|
break;
|
||||||
|
@ -16,14 +16,13 @@ rootProject.ext.createGccConfig = { boolean release, BinaryKind binKind ->
|
|||||||
'linux': null,
|
'linux': null,
|
||||||
'__linux__': null,
|
'__linux__': null,
|
||||||
'NDEBUG': null,
|
'NDEBUG': null,
|
||||||
'_GLIBCXX_USE_CXX11_ABI': 0, // don't use specific c++11 features from GCC 5.X for backward compatibility to earlier version ABI libstdc++.so.6
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
||||||
stripSymbolTable: false,
|
stripSymbolTable: false,
|
||||||
staticLibGcc: false,
|
staticLibGcc: false,
|
||||||
staticLibStdCpp: false,
|
staticLibStdCpp: true,
|
||||||
),
|
),
|
||||||
|
|
||||||
librarianOptions: new GccToolchainConfig.LibrarianOptions(
|
librarianOptions: new GccToolchainConfig.LibrarianOptions(
|
||||||
@ -42,14 +41,13 @@ rootProject.ext.createGccConfig = { boolean release, BinaryKind binKind ->
|
|||||||
'linux': null,
|
'linux': null,
|
||||||
'__linux__': null,
|
'__linux__': null,
|
||||||
'NDEBUG': null,
|
'NDEBUG': null,
|
||||||
'_GLIBCXX_USE_CXX11_ABI': 0, // don't use specific c++11 features from GCC 5.X for backward compatibility to earlier version ABI libstdc++.so.6
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
||||||
stripSymbolTable: false,
|
stripSymbolTable: false,
|
||||||
staticLibGcc: false,
|
staticLibGcc: false,
|
||||||
staticLibStdCpp: false,
|
staticLibStdCpp: true,
|
||||||
),
|
),
|
||||||
|
|
||||||
librarianOptions: new GccToolchainConfig.LibrarianOptions(
|
librarianOptions: new GccToolchainConfig.LibrarianOptions(
|
||||||
|
@ -19,14 +19,13 @@ rootProject.ext.createIccConfig = { boolean release, BinaryKind binKind ->
|
|||||||
'linux': null,
|
'linux': null,
|
||||||
'__linux__': null,
|
'__linux__': null,
|
||||||
'NDEBUG': null,
|
'NDEBUG': null,
|
||||||
'_GLIBCXX_USE_CXX11_ABI': 0, // don't use specific c++11 features from GCC 5.X for backward compatibility to earlier version ABI libstdc++.so.6
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
||||||
interProceduralOptimizations: true, // -ipo
|
interProceduralOptimizations: true, // -ipo
|
||||||
stripSymbolTable: true,
|
stripSymbolTable: true,
|
||||||
staticLibStdCpp: false,
|
staticLibStdCpp: true,
|
||||||
staticLibGcc: false,
|
staticLibGcc: false,
|
||||||
staticIntel: true,
|
staticIntel: true,
|
||||||
),
|
),
|
||||||
@ -49,14 +48,13 @@ rootProject.ext.createIccConfig = { boolean release, BinaryKind binKind ->
|
|||||||
'linux': null,
|
'linux': null,
|
||||||
'__linux__': null,
|
'__linux__': null,
|
||||||
'NDEBUG': null,
|
'NDEBUG': null,
|
||||||
'_GLIBCXX_USE_CXX11_ABI': 0, // don't use specific c++11 features from GCC 5.X for backward compatibility to earlier version ABI libstdc++.so.6
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
linkerOptions: new GccToolchainConfig.LinkerOptions(
|
||||||
interProceduralOptimizations: false,
|
interProceduralOptimizations: false,
|
||||||
stripSymbolTable: false,
|
stripSymbolTable: false,
|
||||||
staticLibStdCpp: false,
|
staticLibStdCpp: true,
|
||||||
staticLibGcc: false,
|
staticLibGcc: false,
|
||||||
staticIntel: true,
|
staticIntel: true,
|
||||||
),
|
),
|
||||||
|
8
version_script.lds
Normal file
8
version_script.lds
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
REAPI_ABI_1.0 {
|
||||||
|
global:
|
||||||
|
Meta_*;
|
||||||
|
GiveFnptrsToDll;
|
||||||
|
AMXX_*;
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user