diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 094a745a92..7c2399726d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,9 +54,9 @@ jobs: # Setup Python for AMBuild - uses: actions/setup-python@v5 - name: Setup Python 3.8 + name: Setup Python 3.9 with: - python-version: 3.8 + python-version: 3.9 - name: Install Python dependencies run: | python -m pip install --upgrade pip setuptools wheel diff --git a/AMBuildScript b/AMBuildScript index 56faedafb4..1baeb1e94c 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -536,7 +536,10 @@ class SMConfig(object): for task in self.libsafetyhook: if task.target.arch == binary.compiler.target.arch: - binary.compiler.linkflags += [task.binary] + if task.target.platform == 'windows': + binary.compiler.linkflags += [task.binary.path.removesuffix('.dll') + '.lib'] + else: + binary.compiler.linkflags += [task.binary] return raise Exception('No suitable build of safetyhook was found.') diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index 4e0e8d88a9..550f55b007 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -676,6 +676,19 @@ void CoreProviderImpl::InitializeBridge() bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength) { char file[PLATFORM_MAX_PATH]; + char myerror[255]; + + /* Load safetyhook first. The core & extensions might depend on it */ + g_SMAPI->PathFormat(file, + sizeof(file), + "%s/bin/" PLATFORM_ARCH_FOLDER "safetyhook." PLATFORM_LIB_EXT, + g_SourceMod.GetSourceModPath()); + + safetyhook_ = ke::SharedLib::Open(file, myerror, sizeof(myerror)); + if (!safetyhook_) { + ke::SafeSprintf(error, maxlength, "failed to load %s: %s", file, myerror); + return false; + } /* Now it's time to load the logic binary */ g_SMAPI->PathFormat(file, @@ -683,7 +696,6 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength) "%s/bin/" PLATFORM_ARCH_FOLDER "sourcemod.logic." PLATFORM_LIB_EXT, g_SourceMod.GetSourceModPath()); - char myerror[255]; logic_ = ke::SharedLib::Open(file, myerror, sizeof(myerror)); if (!logic_) { ke::SafeSprintf(error, maxlength, "failed to load %s: %s", file, myerror); diff --git a/core/provider.h b/core/provider.h index a1ad393fed..cb4546c115 100644 --- a/core/provider.h +++ b/core/provider.h @@ -76,6 +76,7 @@ class CoreProviderImpl : public CoreProvider } private: + ke::RefPtr safetyhook_; ke::RefPtr logic_; LogicInitFunction logic_init_; GameHooks hooks_; diff --git a/extensions/dhooks/DynamicHooks/hook.cpp b/extensions/dhooks/DynamicHooks/hook.cpp index 4454ea37f3..1202e99f52 100644 --- a/extensions/dhooks/DynamicHooks/hook.cpp +++ b/extensions/dhooks/DynamicHooks/hook.cpp @@ -42,7 +42,6 @@ #else #include #include -#include using namespace sp; #endif diff --git a/public/CDetour/detourhelpers.h b/public/CDetour/detourhelpers.h deleted file mode 100644 index 9c9bd2de47..0000000000 --- a/public/CDetour/detourhelpers.h +++ /dev/null @@ -1,147 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id: detourhelpers.h 248 2008-08-27 00:56:22Z pred $ - */ - -#ifndef _INCLUDE_SOURCEMOD_DETOURHELPERS_H_ -#define _INCLUDE_SOURCEMOD_DETOURHELPERS_H_ - -#if defined PLATFORM_POSIX -#include -#define PAGE_EXECUTE_READWRITE PROT_READ|PROT_WRITE|PROT_EXEC -#endif - -#include -#include -#include -#include - -struct patch_t -{ - patch_t() - { - patch[0] = 0; - bytes = 0; - } - unsigned char patch[20]; - size_t bytes; -}; - -inline void ProtectMemory(void *addr, int length, int prot) -{ - char error[256]; -#if defined PLATFORM_POSIX - long pageSize = sysconf(_SC_PAGESIZE); - void *startPage = ke::AlignedBase(addr, pageSize); - void *endPage = ke::AlignedBase((void *)((intptr_t)addr + length), pageSize); - if (mprotect(startPage, ((intptr_t)endPage - (intptr_t)startPage) + pageSize, prot) == -1) { - ke::FormatSystemError(error, sizeof(error)); - fprintf(stderr, "mprotect: %s\n", error); - } -#elif defined PLATFORM_WINDOWS - DWORD old_prot; - if (!VirtualProtect(addr, length, prot, &old_prot)) { - ke::FormatSystemError(error, sizeof(error)); - fprintf(stderr, "VirtualProtect: %s\n", error); - } -#endif -} - -inline void SetMemPatchable(void *address, size_t size) -{ - ProtectMemory(address, (int)size, PAGE_EXECUTE_READWRITE); -} - -inline void PatchRelJump32(unsigned char *target, void *callback) -{ - SetMemPatchable(target, 5); - - // jmp <32-bit displacement> - target[0] = IA32_JMP_IMM32; - *(int32_t *)(&target[1]) = int32_t((unsigned char *)callback - (target + 5)); -} - -inline void PatchAbsJump64(unsigned char *target, void *callback) -{ - int i = 0; - SetMemPatchable(target, 14); - - // push ; allocates 64-bit stack space on x64 - // mov [rsp+4], ; unnecessary if upper bits are 0 - // ret ; jump to address on stack - target[i++] = IA32_PUSH_IMM32; - *(int32_t *)(&target[i]) = int32_t(int64_t(callback)); - i += 4; - if ((int64_t(callback) >> 32) != 0) - { - target[i++] = IA32_MOV_RM_IMM32; - target[i++] = ia32_modrm(MOD_DISP8, 0, kREG_SIB); - target[i++] = ia32_sib(NOSCALE, kREG_NOIDX, kREG_ESP); - target[i++] = 0x04; - *(int32_t *)(&target[i]) = (int64_t(callback) >> 32); - i += 4; - } - target[i] = IA32_RET; -} - -inline void DoGatePatch(unsigned char *target, void *callback) -{ -#if defined(_WIN64) || defined(__x86_64__) - int64_t diff = int64_t(callback) - (int64_t(target) + 5); - int32_t upperBits = (diff >> 32); - if (upperBits == 0 || upperBits == -1) - PatchRelJump32(target, callback); - else - PatchAbsJump64(target, callback); -#else - PatchRelJump32(target, callback); -#endif -} - -inline void ApplyPatch(void *address, int offset, const patch_t *patch, patch_t *restore) -{ - unsigned char *addr = (unsigned char *)address + offset; - SetMemPatchable(addr, patch->bytes); - - if (restore) - { - for (size_t i=0; ibytes; i++) - { - restore->patch[i] = addr[i]; - } - restore->bytes = patch->bytes; - } - - for (size_t i=0; ibytes; i++) - { - addr[i] = patch->patch[i]; - } -} - -#endif //_INCLUDE_SOURCEMOD_DETOURHELPERS_H_ diff --git a/public/CDetour/detours.h b/public/CDetour/detours.h index 43e16e245b..bd6480bd4f 100644 --- a/public/CDetour/detours.h +++ b/public/CDetour/detours.h @@ -32,6 +32,7 @@ #ifndef _INCLUDE_SOURCEMOD_DETOURS_H_ #define _INCLUDE_SOURCEMOD_DETOURS_H_ +#define SAFETYHOOK_SHARED_LIB true #include "safetyhook.hpp" #include diff --git a/public/safetyhook b/public/safetyhook index ab76f94ee4..238f938e55 160000 --- a/public/safetyhook +++ b/public/safetyhook @@ -1 +1 @@ -Subproject commit ab76f94ee4ef28187cc08030599577996fcba3be +Subproject commit 238f938e55ddadafd5a6d2f6c2cff58dedf69891 diff --git a/tools/buildbot/PackageScript b/tools/buildbot/PackageScript index 14d77b5d01..976f340adb 100644 --- a/tools/buildbot/PackageScript +++ b/tools/buildbot/PackageScript @@ -50,6 +50,13 @@ helpers = SM.package_helpers helpers.builder = builder folder_map = helpers.CreateFolders(folder_list) +# Copy safetyhook +for cxx_task in SM.libsafetyhook: + if cxx_task.target.arch == 'x86_64' in cxx_task.binary.path: + builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/bin/x64']) + else: + builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/bin']) + # Copy binaries. for cxx_task in SM.binaries: # mms expects our loader (sourcemod_mm) to exist in /bin/