64-bit support for CSGO on Linux and macOS (#705)

This commit is contained in:
Scott Ehlert 2017-12-20 01:56:23 -06:00 committed by GitHub
parent 057a5790e2
commit ce1a4dcac0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
90 changed files with 15682 additions and 947 deletions

View File

@ -11,10 +11,29 @@ class SDK(object):
self.platform = platform
self.name = dir
self.path = None # Actual path
self.platformSpec = platform
# By default, nothing supports x64.
if type(platform) is list:
self.platformSpec = {p: ['x86'] for p in platform}
else:
self.platformSpec = platform
def shouldBuild(self, target, archs):
if target.platform not in self.platformSpec:
return False
if not len([i for i in self.platformSpec[target.platform] if i in archs]):
return False
return True
WinOnly = ['windows']
WinLinux = ['windows', 'linux']
WinLinuxMac = ['windows', 'linux', 'mac']
CSGO = {
'windows': ['x86'],
'linux': ['x86', 'x64'],
'mac': ['x64']
}
PossibleSDKs = {
'episode1': SDK('HL2SDK', '2.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'),
@ -31,7 +50,7 @@ PossibleSDKs = {
'swarm': SDK('HL2SDK-SWARM', '2.swarm', '16', 'ALIENSWARM', WinOnly, 'swarm'),
'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'),
'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'),
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', WinLinux, 'csgo'),
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', CSGO, 'csgo'),
'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '17', 'PORTAL2', [], 'portal2'),
'blade': SDK('HL2SDKBLADE', '2.blade', '18', 'BLADE', WinLinux, 'blade'),
'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '19', 'INSURGENCY', WinLinuxMac, 'insurgency'),
@ -61,6 +80,28 @@ def ResolveEnvPath(env, folder):
def Normalize(path):
return os.path.abspath(os.path.normpath(path))
def SetArchFlags(compiler, arch, platform):
if compiler.behavior == 'gcc':
if arch == 'x86':
compiler.cflags += ['-m32']
compiler.linkflags += ['-m32']
if platform == 'mac':
compiler.linkflags += ['-arch', 'i386']
elif arch == 'x64':
compiler.cflags += ['-m64', '-fPIC']
compiler.linkflags += ['-m64']
if platform == 'mac':
compiler.linkflags += ['-arch', 'x86_64']
elif compiler.like('msvc'):
if builder.target.arch == 'x86':
compiler.linkflags += ['/MACHINE:X86']
elif builder.target.arch == 'x64':
compiler.linkflags += ['/MACHINE:X64']
def AppendArchSuffix(binary, name, arch):
if arch == 'x64':
binary.localFolder = name + '.x64'
class SMConfig(object):
def __init__(self):
self.sdks = {}
@ -68,10 +109,12 @@ class SMConfig(object):
self.extensions = []
self.generated_headers = None
self.mms_root = None
self.mysql_root = None
self.mysql_root = {}
self.spcomp = None
self.spcomp_bins = None
self.smx_files = {}
self.versionlib = None
self.archs = builder.target.arch.replace('x86_64', 'x64').split(',')
def use_auto_versioning(self):
if builder.backend != 'amb2':
@ -105,7 +148,7 @@ class SMConfig(object):
for sdk_name in PossibleSDKs:
sdk = PossibleSDKs[sdk_name]
if builder.target.platform in sdk.platform:
if sdk.shouldBuild(builder.target, self.archs):
if builder.options.hl2sdk_root:
sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder)
else:
@ -118,8 +161,9 @@ class SMConfig(object):
sdk.path = Normalize(sdk_path)
self.sdks[sdk_name] = sdk
if len(self.sdks) < 1:
raise Exception('At least one SDK must be available.')
if len(self.sdks) < 1 and len(sdk_list):
raise Exception('No SDKs were found that build on {0}-{1}, nothing to do.'.format(
builder.target.platform, builder.target.arch))
if builder.options.mms_path:
self.mms_root = builder.options.mms_path
@ -136,21 +180,40 @@ class SMConfig(object):
if builder.options.hasMySql:
if builder.options.mysql_path:
self.mysql_root = builder.options.mysql_path
self.mysql_root['x86'] = builder.options.mysql_path
else:
for i in range(7):
self.mysql_root = ResolveEnvPath('MYSQL5', 'mysql-5.' + str(i))
if self.mysql_root:
self.mysql_root['x86'] = ResolveEnvPath('MYSQL5', 'mysql-5.' + str(i))
if self.mysql_root['x86']:
break
if not self.mysql_root or not os.path.isdir(self.mysql_root):
if not self.mysql_root['x86'] or not os.path.isdir(self.mysql_root['x86']):
raise Exception('Could not find a path to MySQL!')
self.mysql_root = Normalize(self.mysql_root)
self.mysql_root['x86'] = Normalize(self.mysql_root['x86'])
# For now, ignore 64-bit MySQL on Windows
if 'x64' in self.archs and builder.target.platform != 'windows':
if builder.options.mysql_path:
self.mysql_root['x64'] = builder.options.mysql64_path
else:
for i in range(7):
self.mysql_root['x64'] = ResolveEnvPath('MYSQL5_64', 'mysql-5.' + str(i) + '-x86_64')
if self.mysql_root['x64']:
break
if not self.mysql_root['x64'] or not os.path.isdir(self.mysql_root['x64']):
raise Exception('Could not find a path to 64-bit MySQL!')
self.mysql_root['x64'] = Normalize(self.mysql_root['x64'])
def configure(self):
builder.AddConfigureFile('pushbuild.txt')
if not set(self.archs).issubset(['x86', 'x64']):
raise Exception('Unknown target architecture: {0}'.format(builder.target.arch))
cxx = builder.DetectCxx()
if cxx.like('msvc') and len(self.archs) > 1:
raise Exception('Building multiple archs with MSVC is not currently supported')
if cxx.like('gcc'):
self.configure_gcc(cxx)
elif cxx.family == 'msvc':
@ -205,7 +268,6 @@ class SMConfig(object):
'-Wno-switch',
'-Wno-array-bounds',
'-msse',
'-m32',
'-fvisibility=hidden',
]
cxx.cxxflags += [
@ -216,7 +278,6 @@ class SMConfig(object):
'-Wno-overloaded-virtual',
'-fvisibility-inlines-hidden',
]
cxx.linkflags += ['-m32']
have_gcc = cxx.family == 'gcc'
have_clang = cxx.family == 'clang'
@ -271,7 +332,6 @@ class SMConfig(object):
'/TP',
]
cxx.linkflags += [
'/MACHINE:X86',
'kernel32.lib',
'user32.lib',
'gdi32.lib',
@ -310,7 +370,6 @@ class SMConfig(object):
cxx.cflags += ['-mmacosx-version-min=10.5']
cxx.linkflags += [
'-mmacosx-version-min=10.5',
'-arch', 'i386',
'-lstdc++',
'-stdlib=libstdc++',
]
@ -319,7 +378,7 @@ class SMConfig(object):
def configure_windows(self, cxx):
cxx.defines += ['WIN32', '_WINDOWS']
def AddVersioning(self, binary):
def AddVersioning(self, binary, arch):
if builder.target.platform == 'windows':
binary.sources += ['version.rc']
binary.compiler.rcdefines += [
@ -335,20 +394,22 @@ class SMConfig(object):
'-current_version', self.productVersion
]
if self.use_auto_versioning():
binary.compiler.linkflags += [self.versionlib]
binary.compiler.linkflags += [self.versionlib[arch]]
binary.compiler.sourcedeps += SM.generated_headers
return binary
def LibraryBuilder(self, compiler, name):
def LibraryBuilder(self, compiler, name, arch):
binary = compiler.Library(name)
self.AddVersioning(binary)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
if binary.compiler.like('msvc'):
binary.compiler.linkflags += ['/SUBSYSTEM:WINDOWS']
return binary
def ProgramBuilder(self, compiler, name):
def ProgramBuilder(self, compiler, name, arch):
binary = compiler.Program(name)
self.AddVersioning(binary)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
if '-static-libgcc' in binary.compiler.linkflags:
binary.compiler.linkflags.remove('-static-libgcc')
if '-lgcc_eh' in binary.compiler.linkflags:
@ -359,21 +420,25 @@ class SMConfig(object):
binary.compiler.linkflags += ['/SUBSYSTEM:CONSOLE']
return binary
def StaticLibraryBuilder(self, compiler, name):
def StaticLibraryBuilder(self, compiler, name, arch):
binary = compiler.StaticLibrary(name)
AppendArchSuffix(binary, name, arch)
return binary;
def Library(self, context, name):
def Library(self, context, name, arch):
compiler = context.cxx.clone()
return self.LibraryBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.LibraryBuilder(compiler, name, arch)
def Program(self, context, name):
def Program(self, context, name, arch):
compiler = context.cxx.clone()
return self.ProgramBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.ProgramBuilder(compiler, name, arch)
def StaticLibrary(self, context, name):
def StaticLibrary(self, context, name, arch):
compiler = context.cxx.clone()
return self.StaticLibraryBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.StaticLibraryBuilder(compiler, name, arch)
def ConfigureForExtension(self, context, compiler):
compiler.cxxincludes += [
@ -386,14 +451,16 @@ class SMConfig(object):
]
return compiler
def ExtLibrary(self, context, name):
binary = self.Library(context, name)
def ExtLibrary(self, context, name, arch):
binary = self.Library(context, name, arch)
self.ConfigureForExtension(context, binary.compiler)
return binary
def ConfigureForHL2(self, binary, sdk):
def ConfigureForHL2(self, binary, sdk, arch):
compiler = binary.compiler
SetArchFlags(compiler, arch, builder.target.platform)
compiler.cxxincludes += [
os.path.join(self.mms_root, 'core'),
os.path.join(self.mms_root, 'core', 'sourcehook'),
@ -435,6 +502,9 @@ class SMConfig(object):
else:
compiler.defines += ['COMPILER_GCC']
if arch == 'x64':
compiler.defines += ['X64BITS', 'PLATFORM_64BITS']
# For everything after Swarm, this needs to be defined for entity networking
# to work properly with sendprop value changes.
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
@ -446,6 +516,7 @@ class SMConfig(object):
if sdk.name == 'csgo' and builder.target.platform == 'linux':
compiler.linkflags += ['-lstdc++']
compiler.defines += ['_GLIBCXX_USE_CXX11_ABI=0']
for path in paths:
compiler.cxxincludes += [os.path.join(sdk.path, *path)]
@ -455,16 +526,20 @@ class SMConfig(object):
lib_folder = os.path.join(sdk.path, 'linux_sdk')
elif sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32')
elif arch == 'x64':
lib_folder = os.path.join(sdk.path, 'lib', 'linux64')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'linux')
elif builder.target.platform == 'mac':
if sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32')
elif arch == 'x64':
lib_folder = os.path.join(sdk.path, 'lib', 'osx64')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'mac')
if builder.target.platform in ['linux', 'mac']:
if sdk.name in ['sdk2013', 'bms']:
if sdk.name in ['sdk2013', 'bms'] or arch == 'x64':
compiler.postlink += [
compiler.Dep(os.path.join(lib_folder, 'tier1.a')),
compiler.Dep(os.path.join(lib_folder, 'mathlib.a'))
@ -476,12 +551,17 @@ class SMConfig(object):
]
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))]
if arch == 'x64':
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces.a'))]
else:
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))]
dynamic_libs = []
if builder.target.platform == 'linux':
if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2', 'insurgency', 'doi']:
dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so']
elif arch == 'x64' and sdk.name == 'csgo':
dynamic_libs = ['libtier0_client.so', 'libvstdlib_client.so']
elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo']:
dynamic_libs = ['libtier0.so', 'libvstdlib.so']
else:
@ -512,20 +592,21 @@ class SMConfig(object):
return binary
def HL2Library(self, context, name, sdk):
binary = self.Library(context, name)
def HL2Library(self, context, name, sdk, arch):
binary = self.Library(context, name, arch)
self.ConfigureForExtension(context, binary.compiler)
return self.ConfigureForHL2(binary, sdk)
return self.ConfigureForHL2(binary, sdk, arch)
def HL2Project(self, context, name):
project = context.cxx.LibraryProject(name)
self.ConfigureForExtension(context, project.compiler)
return project
def HL2Config(self, project, name, sdk):
def HL2Config(self, project, name, sdk, arch):
binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name))
self.AddVersioning(binary)
return self.ConfigureForHL2(binary, sdk)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
return self.ConfigureForHL2(binary, sdk, arch)
SM = SMConfig()
SM.detectProductVersion()
@ -548,10 +629,15 @@ SP = builder.Build('sourcepawn/AMBuildScript', {
'external_amtl': os.path.join(builder.sourcePath, 'public', 'amtl'),
'external_build': ['core'],
})
SM.spcomp = SP.spcomp
SM.binaries += [
SP.libsourcepawn
]
if len(SP.spcomp) > 1:
SM.spcomp = SP.spcomp['x86']
else:
SM.spcomp = SP.spcomp[list(SP.spcomp.keys())[0]]
SM.spcomp_bins = list(SP.spcomp.values())
for arch in SM.archs:
SM.binaries += [
SP.libsourcepawn[arch]
]
BuildScripts = [
'loader/AMBuilder',

View File

@ -35,7 +35,7 @@ namespace SourceMod {
// Add 1 to the RHS of this expression to bump the intercom file
// This is to prevent mismatching core/logic binaries
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 55;
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 56;
} // namespace SourceMod

View File

@ -74,6 +74,8 @@ struct sm_logic_t
void (*FreeDataPack)(IDataPack *pack);
ICellArray * (*CreateCellArray)(size_t blocksize);
void (*FreeCellArray)(ICellArray *arr);
void * (*FromPseudoAddress)(uint32_t pseudoAddr);
uint32_t (*ToPseudoAddress)(void *addr);
IScriptManager *scripts;
IShareSys *sharesys;
IExtensionSys *extsys;

View File

@ -22,6 +22,8 @@ parser.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default
help='Root search folder for HL2SDKs')
parser.options.add_option('--mysql-path', type=str, dest='mysql_path', default=None,
help='Path to MySQL 5')
parser.options.add_option('--mysql64-path', type=str, dest='mysql64_path', default=None,
help='Path to 64-bit MySQL 5')
parser.options.add_option('--mms-path', type=str, dest='mms_path', default=None,
help='Path to Metamod:Source')
parser.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',

View File

@ -44,60 +44,70 @@ project.sources += [
for sdk_name in SM.sdks:
sdk = SM.sdks[sdk_name]
binary_name = 'sourcemod.' + sdk.ext
for arch in SM.archs:
if not arch in sdk.platformSpec[builder.target.platform]:
continue
binary = SM.HL2Config(project, binary_name, sdk)
compiler = binary.compiler
binary_name = 'sourcemod.' + sdk.ext
compiler.cxxincludes += [
builder.sourcePath
]
binary = SM.HL2Config(project, binary_name, sdk, arch)
compiler = binary.compiler
if sdk.name == 'csgo':
compiler.cxxincludes += [
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
builder.sourcePath
]
if builder.target.platform == 'linux':
compiler.postlink += ['-lpthread', '-lrt']
if sdk.name == 'csgo':
compiler.cxxincludes += [
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
]
if sdk.name == 'csgo':
if builder.target.platform == 'linux':
lib_path = os.path.join(sdk.path, 'lib', 'linux32', 'release', 'libprotobuf.a')
compiler.linkflags += ['-Wl,--exclude-libs=libprotobuf.a']
elif builder.target.platform == 'mac':
lib_path = os.path.join(sdk.path, 'lib', 'osx32', 'release', 'libprotobuf.a')
elif builder.target.platform == 'windows':
msvc_ver = compiler.version
vs_year = ''
if msvc_ver == 1800:
vs_year = '2013'
elif msvc_ver == 1900:
vs_year = '2015'
elif msvc_ver == 1910:
vs_year = '2017'
else:
raise Exception('Cannot find libprotobuf for MSVC version "' + str(compiler.version) + '"')
compiler.postlink += ['-lpthread', '-lrt']
if 'DEBUG' in compiler.defines:
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'debug', 'vs' + vs_year, 'libprotobuf.lib')
else:
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'release', 'vs' + vs_year, 'libprotobuf.lib')
compiler.linkflags.insert(0, binary.Dep(lib_path))
if sdk.name == 'csgo':
if builder.target.platform == 'linux':
if arch == 'x86':
lib_path = os.path.join(sdk.path, 'lib', 'linux32', 'release', 'libprotobuf.a')
elif arch == 'x64':
lib_path = os.path.join(sdk.path, 'lib', 'linux64', 'release', 'libprotobuf.a')
compiler.linkflags += ['-Wl,--exclude-libs=libprotobuf.a']
elif builder.target.platform == 'mac':
if arch == 'x86':
lib_path = os.path.join(sdk.path, 'lib', 'osx32', 'release', 'libprotobuf.a')
elif arch == 'x64':
lib_path = os.path.join(sdk.path, 'lib', 'osx64', 'release', 'libprotobuf.a')
elif builder.target.platform == 'windows':
msvc_ver = compiler.version
vs_year = ''
if msvc_ver == 1800:
vs_year = '2013'
elif msvc_ver == 1900:
vs_year = '2015'
elif msvc_ver == 1910:
vs_year = '2017'
else:
raise Exception('Cannot find libprotobuf for MSVC version "' + str(compiler.version) + '"')
if sdk.name == 'csgo':
binary.sources += ['smn_protobuf.cpp']
else:
binary.sources += ['smn_bitbuffer.cpp']
if 'DEBUG' in compiler.defines:
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'debug', 'vs' + vs_year, 'libprotobuf.lib')
else:
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'release', 'vs' + vs_year, 'libprotobuf.lib')
compiler.linkflags.insert(0, binary.Dep(lib_path))
if sdk.name == 'csgo':
binary.sources += [
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessage_helpers.cpp'),
]
if sdk.name == 'csgo':
binary.sources += ['smn_protobuf.cpp']
else:
binary.sources += ['smn_bitbuffer.cpp']
if sdk.name == 'csgo':
binary.sources += [
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessage_helpers.cpp'),
]
SM.binaries += builder.Add(project)

View File

@ -364,8 +364,8 @@ void EventManager::FireEvent(EventInfo *pInfo, bool bDontBroadcast)
void EventManager::FireEventToClient(EventInfo *pInfo, IClient *pClient)
{
// The IClient vtable is +4 from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance.
IGameEventListener2 *pGameClient = (IGameEventListener2 *)((intptr_t)pClient - 4);
// The IClient vtable is +sizeof(void *) from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance.
IGameEventListener2 *pGameClient = (IGameEventListener2 *)((intptr_t)pClient - sizeof(void *));
pGameClient->FireGameEvent(pInfo->pEvent);
}

View File

@ -245,7 +245,12 @@ void CHalfLife2::InitLogicalEntData()
return;
}
#ifdef PLATFORM_X86
g_EntList = *reinterpret_cast<void **>(addr + offset);
#elif defined PLATFORM_X64
int32_t varOffset = *reinterpret_cast<int32_t *>(addr + offset);
g_EntList = reinterpret_cast<void *>(addr + offset + sizeof(int32_t) + varOffset);
#endif
}
}
@ -1357,7 +1362,7 @@ string_t CHalfLife2::AllocPooledString(const char *pszValue)
bool CHalfLife2::GetServerSteam3Id(char *pszOut, size_t len) const
{
CSteamID sid(GetServerSteamId64());
CSteamID sid((uint64)GetServerSteamId64());
switch (sid.GetEAccountType())
{

View File

@ -102,7 +102,7 @@ class KickPlayerTimer : public ITimedEvent
public:
ResultType OnTimer(ITimer *pTimer, void *pData)
{
int userid = (int)pData;
int userid = (int)(intptr_t)pData;
int client = g_Players.GetClientOfUserId(userid);
if (client)
{
@ -2480,7 +2480,7 @@ void CPlayer::DoBasicAdminChecks()
if (!g_Players.CheckSetAdminName(client, this, id))
{
int userid = engine->GetPlayerUserId(m_pEdict);
g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)userid, 0);
g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)(intptr_t)userid, 0);
}
return;
}

View File

@ -1,92 +1,97 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.Library(builder, 'sourcemod.logic')
binary.compiler.cxxincludes += [
builder.sourcePath,
os.path.join(builder.sourcePath, 'core', 'logic'),
os.path.join(builder.sourcePath, 'public'),
os.path.join(builder.sourcePath, 'sourcepawn', 'include'),
os.path.join(builder.sourcePath, 'public', 'amtl', 'amtl'),
os.path.join(builder.sourcePath, 'public', 'amtl'),
os.path.join(SM.mms_root, 'core', 'sourcehook')
]
binary.compiler.defines += [
'SM_DEFAULT_THREADER',
'SM_LOGIC'
]
for arch in SM.archs:
binary = SM.Library(builder, 'sourcemod.logic', arch)
binary.compiler.cxxincludes += [
builder.sourcePath,
os.path.join(builder.sourcePath, 'core', 'logic'),
os.path.join(builder.sourcePath, 'public'),
os.path.join(builder.sourcePath, 'sourcepawn', 'include'),
os.path.join(builder.sourcePath, 'public', 'amtl', 'amtl'),
os.path.join(builder.sourcePath, 'public', 'amtl'),
os.path.join(SM.mms_root, 'core', 'sourcehook')
]
binary.compiler.defines += [
'SM_DEFAULT_THREADER',
'SM_LOGIC'
]
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-lpthread', '-lrt']
elif builder.target.platform == 'mac':
binary.compiler.cflags += ['-Wno-deprecated-declarations']
binary.compiler.postlink += ['-framework', 'CoreServices']
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-lpthread', '-lrt']
elif builder.target.platform == 'mac':
binary.compiler.cflags += ['-Wno-deprecated-declarations']
binary.compiler.postlink += ['-framework', 'CoreServices']
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'common_logic.cpp',
'smn_adt_array.cpp',
'smn_sorting.cpp',
'smn_maplists.cpp',
'ADTFactory.cpp',
'smn_adt_stack.cpp',
'thread/ThreadWorker.cpp',
'thread/BaseWorker.cpp',
'ThreadSupport.cpp',
'smn_float.cpp',
'TextParsers.cpp',
'smn_textparse.cpp',
'smn_adt_trie.cpp',
'smn_functions.cpp',
'smn_timers.cpp',
'smn_players.cpp',
'MemoryUtils.cpp',
'smn_admin.cpp',
'smn_banning.cpp',
'smn_filesystem.cpp',
'stringutil.cpp',
'Translator.cpp',
'PhraseCollection.cpp',
'smn_lang.cpp',
'smn_string.cpp',
'smn_handles.cpp',
'smn_datapacks.cpp',
'smn_gameconfigs.cpp',
'smn_fakenatives.cpp',
'GameConfigs.cpp',
'sm_crc32.cpp',
'smn_profiler.cpp',
'ShareSys.cpp',
'PluginSys.cpp',
'HandleSys.cpp',
'NativeOwner.cpp',
'ExtensionSys.cpp',
'DebugReporter.cpp',
'Database.cpp',
'smn_database.cpp',
'ForwardSys.cpp',
'AdminCache.cpp',
'sm_trie.cpp',
'smn_console.cpp',
'ProfileTools.cpp',
'Logger.cpp',
'smn_core.cpp',
'smn_menus.cpp',
'sprintf.cpp',
'LibrarySys.cpp',
'RootConsoleMenu.cpp',
'CDataPack.cpp',
'frame_tasks.cpp',
'smn_halflife.cpp',
'FrameIterator.cpp',
]
if builder.target.platform == 'windows':
binary.sources += ['thread/WinThreads.cpp']
else:
binary.sources += ['thread/PosixThreads.cpp']
binary.sources += [
'common_logic.cpp',
'smn_adt_array.cpp',
'smn_sorting.cpp',
'smn_maplists.cpp',
'ADTFactory.cpp',
'smn_adt_stack.cpp',
'thread/ThreadWorker.cpp',
'thread/BaseWorker.cpp',
'ThreadSupport.cpp',
'smn_float.cpp',
'TextParsers.cpp',
'smn_textparse.cpp',
'smn_adt_trie.cpp',
'smn_functions.cpp',
'smn_timers.cpp',
'smn_players.cpp',
'MemoryUtils.cpp',
'smn_admin.cpp',
'smn_banning.cpp',
'smn_filesystem.cpp',
'stringutil.cpp',
'Translator.cpp',
'PhraseCollection.cpp',
'smn_lang.cpp',
'smn_string.cpp',
'smn_handles.cpp',
'smn_datapacks.cpp',
'smn_gameconfigs.cpp',
'smn_fakenatives.cpp',
'GameConfigs.cpp',
'sm_crc32.cpp',
'smn_profiler.cpp',
'ShareSys.cpp',
'PluginSys.cpp',
'HandleSys.cpp',
'NativeOwner.cpp',
'ExtensionSys.cpp',
'DebugReporter.cpp',
'Database.cpp',
'smn_database.cpp',
'ForwardSys.cpp',
'AdminCache.cpp',
'sm_trie.cpp',
'smn_console.cpp',
'ProfileTools.cpp',
'Logger.cpp',
'smn_core.cpp',
'smn_menus.cpp',
'sprintf.cpp',
'LibrarySys.cpp',
'RootConsoleMenu.cpp',
'CDataPack.cpp',
'frame_tasks.cpp',
'smn_halflife.cpp',
'FrameIterator.cpp',
]
SM.binaries += [builder.Add(binary)]
if arch == 'x64':
binary.sources += ['PseudoAddrManager.cpp']
if builder.target.platform == 'windows':
binary.sources += ['thread/WinThreads.cpp']
else:
binary.sources += ['thread/PosixThreads.cpp']
SM.binaries += [builder.Add(binary)]

View File

@ -80,7 +80,7 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.%s." PLATFORM_LIB_EXT,
"extensions/" PLATFORM_ARCH_FOLDER "%s.%s." PLATFORM_LIB_EXT,
filename,
bridge->gamesuffix);
@ -98,7 +98,7 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.2.ep2v." PLATFORM_LIB_EXT,
"extensions/" PLATFORM_ARCH_FOLDER "%s.2.ep2v." PLATFORM_LIB_EXT,
filename);
if (libsys->IsPathFile(path))
@ -111,7 +111,7 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.2.l4d2." PLATFORM_LIB_EXT,
"extensions/" PLATFORM_ARCH_FOLDER "%s.2.l4d2." PLATFORM_LIB_EXT,
filename);
if (libsys->IsPathFile(path))
@ -124,7 +124,7 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/auto.%s/%s." PLATFORM_LIB_EXT,
"extensions/" PLATFORM_ARCH_FOLDER "auto.%s/%s." PLATFORM_LIB_EXT,
filename,
bridge->gamesuffix);
@ -135,7 +135,7 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s." PLATFORM_LIB_EXT,
"extensions/" PLATFORM_ARCH_FOLDER "%s." PLATFORM_LIB_EXT,
filename);
}

View File

@ -76,16 +76,22 @@ static const char *g_pParseEngine = NULL;
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS 13
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ 14
#if defined PLATFORM_X86
#define PLATFORM_ARCH_SUFFIX ""
#elif defined PLATFORM_X64
#define PLATFORM_ARCH_SUFFIX "64"
#endif
#if defined PLATFORM_WINDOWS
#define PLATFORM_NAME "windows"
#define PLATFORM_NAME "windows" PLATFORM_ARCH_SUFFIX
#define PLATFORM_SERVER_BINARY "server.dll"
#elif defined PLATFORM_LINUX
#define PLATFORM_NAME "linux"
#define PLATFORM_COMPAT_ALT "mac" /* Alternate platform name if game data is missing for primary one */
#define PLATFORM_NAME "linux" PLATFORM_ARCH_SUFFIX
#define PLATFORM_COMPAT_ALT "mac" PLATFORM_ARCH_SUFFIX /* Alternate platform name if game data is missing for primary one */
#define PLATFORM_SERVER_BINARY "server_i486.so"
#elif defined PLATFORM_APPLE
#define PLATFORM_NAME "mac"
#define PLATFORM_COMPAT_ALT "linux"
#define PLATFORM_NAME "mac" PLATFORM_ARCH_SUFFIX
#define PLATFORM_COMPAT_ALT "linux" PLATFORM_ARCH_SUFFIX
#define PLATFORM_SERVER_BINARY "server.dylib"
#endif
@ -338,7 +344,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
}
else
{
if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0)
if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0 &&
strcmp(name, "linux64") != 0 && strcmp(name, "windows64") != 0 && strcmp(name, "mac64") != 0)
{
logger->LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile);
logger->LogError("[SM] Unrecognized platform \"%s\"", name);

View File

@ -125,7 +125,9 @@ bool CDirectory::IsEntryDirectory()
return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
#elif defined PLATFORM_POSIX
char temppath[PLATFORM_MAX_PATH];
snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
int ret = snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
if (static_cast<size_t>(ret) >= sizeof(temppath))
return false;
return ke::file::IsDirectory(temppath);
#endif
}
@ -136,7 +138,9 @@ bool CDirectory::IsEntryFile()
return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
#elif defined PLATFORM_POSIX
char temppath[PLATFORM_MAX_PATH];
snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
int ret = snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
if (static_cast<size_t>(ret) >= sizeof(temppath))
return false;
return ke::file::IsFile(temppath);
#endif
}

View File

@ -43,18 +43,6 @@
#include <mach-o/dyld_images.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
/* Define things from 10.6 SDK for older SDKs */
#ifndef MAC_OS_X_VERSION_10_6
struct task_dyld_info
{
mach_vm_address_t all_image_info_addr;
mach_vm_size_t all_image_info_size;
};
typedef struct task_dyld_info task_dyld_info_data_t;
#define TASK_DYLD_INFO 17
#define TASK_DYLD_INFO_COUNT (sizeof(task_dyld_info_data_t) / sizeof(natural_t))
#endif // MAC_OS_X_VERSION_10_6
#endif // PLATFORM_APPLE
MemoryUtils g_MemUtils;
@ -63,25 +51,10 @@ MemoryUtils::MemoryUtils()
{
#ifdef PLATFORM_APPLE
Gestalt(gestaltSystemVersionMajor, &m_OSXMajor);
Gestalt(gestaltSystemVersionMinor, &m_OSXMinor);
/* Get pointer to struct that describes all loaded mach-o images in process */
if ((m_OSXMajor == 10 && m_OSXMinor >= 6) || m_OSXMajor > 10)
{
task_dyld_info_data_t dyld_info;
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
m_ImageList = (struct dyld_all_image_infos *)dyld_info.all_image_info_addr;
}
else
{
struct nlist list[2];
memset(list, 0, sizeof(list));
list[0].n_un.n_name = (char *)"_dyld_all_image_infos";
nlist("/usr/lib/dyld", list);
m_ImageList = (struct dyld_all_image_infos *)list[0].n_value;
}
task_dyld_info_data_t dyld_info;
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
m_ImageList = (struct dyld_all_image_infos *)dyld_info.all_image_info_addr;
#endif
}
@ -147,13 +120,25 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
#elif defined PLATFORM_LINUX
#ifdef PLATFORM_X86
typedef Elf32_Ehdr ElfHeader;
typedef Elf32_Shdr ElfSHeader;
typedef Elf32_Sym ElfSymbol;
#define ELF_SYM_TYPE ELF32_ST_TYPE
#else
typedef Elf64_Ehdr ElfHeader;
typedef Elf64_Shdr ElfSHeader;
typedef Elf64_Sym ElfSymbol;
#define ELF_SYM_TYPE ELF64_ST_TYPE
#endif
struct link_map *dlmap;
struct stat dlstat;
int dlfile;
uintptr_t map_base;
Elf32_Ehdr *file_hdr;
Elf32_Shdr *sections, *shstrtab_hdr, *symtab_hdr, *strtab_hdr;
Elf32_Sym *symtab;
ElfHeader *file_hdr;
ElfSHeader *sections, *shstrtab_hdr, *symtab_hdr, *strtab_hdr;
ElfSymbol *symtab;
const char *shstrtab, *strtab;
uint16_t section_count;
uint32_t symbol_count;
@ -204,7 +189,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
}
/* Map library file into memory */
file_hdr = (Elf32_Ehdr *)mmap(NULL, dlstat.st_size, PROT_READ, MAP_PRIVATE, dlfile, 0);
file_hdr = (ElfHeader *)mmap(NULL, dlstat.st_size, PROT_READ, MAP_PRIVATE, dlfile, 0);
map_base = (uintptr_t)file_hdr;
if (file_hdr == MAP_FAILED)
{
@ -219,7 +204,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
return NULL;
}
sections = (Elf32_Shdr *)(map_base + file_hdr->e_shoff);
sections = (ElfSHeader *)(map_base + file_hdr->e_shoff);
section_count = file_hdr->e_shnum;
/* Get ELF section header string table */
shstrtab_hdr = &sections[file_hdr->e_shstrndx];
@ -228,7 +213,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
/* Iterate sections while looking for ELF symbol table and string table */
for (uint16_t i = 0; i < section_count; i++)
{
Elf32_Shdr &hdr = sections[i];
ElfSHeader &hdr = sections[i];
const char *section_name = shstrtab + hdr.sh_name;
if (strcmp(section_name, ".symtab") == 0)
@ -248,15 +233,15 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
return NULL;
}
symtab = (Elf32_Sym *)(map_base + symtab_hdr->sh_offset);
symtab = (ElfSymbol *)(map_base + symtab_hdr->sh_offset);
strtab = (const char *)(map_base + strtab_hdr->sh_offset);
symbol_count = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
/* Iterate symbol table starting from the position we were at last time */
for (uint32_t i = libtable->last_pos; i < symbol_count; i++)
{
Elf32_Sym &sym = symtab[i];
unsigned char sym_type = ELF32_ST_TYPE(sym.st_info);
ElfSymbol &sym = symtab[i];
unsigned char sym_type = ELF_SYM_TYPE(sym.st_info);
const char *sym_name = strtab + sym.st_name;
Symbol *cur_sym;
@ -281,13 +266,28 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
#elif defined PLATFORM_APPLE
#ifdef PLATFORM_X86
typedef struct mach_header MachHeader;
typedef struct segment_command MachSegment;
typedef struct nlist MachSymbol;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT;
#else
typedef struct mach_header_64 MachHeader;
typedef struct segment_command_64 MachSegment;
typedef struct nlist_64 MachSymbol;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT_64;
#endif
typedef struct load_command MachLoadCmd;
typedef struct symtab_command MachSymHeader;
uintptr_t dlbase, linkedit_addr;
uint32_t image_count;
struct mach_header *file_hdr;
struct load_command *loadcmds;
struct segment_command *linkedit_hdr;
struct symtab_command *symtab_hdr;
struct nlist *symtab;
MachHeader *file_hdr;
MachLoadCmd *loadcmds;
MachSegment *linkedit_hdr;
MachSymHeader *symtab_hdr;
MachSymbol *symtab;
const char *strtab;
uint32_t loadcmd_count;
uint32_t symbol_count;
@ -357,16 +357,16 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
/* If symbol isn't in our table, then we have to locate it in memory */
file_hdr = (struct mach_header *)dlbase;
loadcmds = (struct load_command *)(dlbase + sizeof(struct mach_header));
file_hdr = (MachHeader *)dlbase;
loadcmds = (MachLoadCmd *)(dlbase + sizeof(MachHeader));
loadcmd_count = file_hdr->ncmds;
/* Loop through load commands until we find the ones for the symbol table */
for (uint32_t i = 0; i < loadcmd_count; i++)
{
if (loadcmds->cmd == LC_SEGMENT && !linkedit_hdr)
if (loadcmds->cmd == MACH_LOADCMD_SEGMENT && !linkedit_hdr)
{
struct segment_command *seg = (struct segment_command *)loadcmds;
MachSegment *seg = (MachSegment *)loadcmds;
if (strcmp(seg->segname, "__LINKEDIT") == 0)
{
linkedit_hdr = seg;
@ -378,7 +378,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
}
else if (loadcmds->cmd == LC_SYMTAB)
{
symtab_hdr = (struct symtab_command *)loadcmds;
symtab_hdr = (MachSymHeader *)loadcmds;
if (linkedit_hdr)
{
break;
@ -386,7 +386,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
}
/* Load commands are not of a fixed size which is why we add the size */
loadcmds = (struct load_command *)((uintptr_t)loadcmds + loadcmds->cmdsize);
loadcmds = (MachLoadCmd *)((uintptr_t)loadcmds + loadcmds->cmdsize);
}
if (!linkedit_hdr || !symtab_hdr || !symtab_hdr->symoff || !symtab_hdr->stroff)
@ -396,14 +396,14 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
}
linkedit_addr = dlbase + linkedit_hdr->vmaddr;
symtab = (struct nlist *)(linkedit_addr + symtab_hdr->symoff - linkedit_hdr->fileoff);
symtab = (MachSymbol *)(linkedit_addr + symtab_hdr->symoff - linkedit_hdr->fileoff);
strtab = (const char *)(linkedit_addr + symtab_hdr->stroff - linkedit_hdr->fileoff);
symbol_count = symtab_hdr->nsyms;
/* Iterate symbol table starting from the position we were at last time */
for (uint32_t i = libtable->last_pos; i < symbol_count; i++)
{
struct nlist &sym = symtab[i];
MachSymbol &sym = symtab[i];
/* Ignore the prepended underscore on all symbols, so +1 here */
const char *sym_name = strtab + sym.n_un.n_strx + 1;
Symbol *cur_sym;
@ -440,6 +440,12 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#ifdef PLATFORM_WINDOWS
#ifdef PLATFORM_X86
const WORD PE_FILE_MACHINE = IMAGE_FILE_MACHINE_I386;
#else
const WORD PE_FILE_MACHINE = IMAGE_FILE_MACHINE_AMD64;
#endif
MEMORY_BASIC_INFORMATION info;
IMAGE_DOS_HEADER *dos;
IMAGE_NT_HEADERS *pe;
@ -465,10 +471,8 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
return false;
}
/* Check architecture, which is 32-bit/x86 right now
* Should change this for 64-bit if Valve gets their act together
*/
if (file->Machine != IMAGE_FILE_MACHINE_I386)
/* Check architecture */
if (file->Machine != PE_FILE_MACHINE)
{
return false;
}
@ -484,9 +488,21 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#elif defined PLATFORM_LINUX
#ifdef PLATFORM_X86
typedef Elf32_Ehdr ElfHeader;
typedef Elf32_Phdr ElfPHeader;
const unsigned char ELF_CLASS = ELFCLASS32;
const uint16_t ELF_MACHINE = EM_386;
#else
typedef Elf64_Ehdr ElfHeader;
typedef Elf64_Phdr ElfPHeader;
const unsigned char ELF_CLASS = ELFCLASS64;
const uint16_t ELF_MACHINE = EM_X86_64;
#endif
Dl_info info;
Elf32_Ehdr *file;
Elf32_Phdr *phdr;
ElfHeader *file;
ElfPHeader *phdr;
uint16_t phdrCount;
if (!dladdr(libPtr, &info))
@ -501,7 +517,7 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
/* This is for our insane sanity checks :o */
baseAddr = reinterpret_cast<uintptr_t>(info.dli_fbase);
file = reinterpret_cast<Elf32_Ehdr *>(baseAddr);
file = reinterpret_cast<ElfHeader *>(baseAddr);
/* Check ELF magic */
if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
@ -515,10 +531,14 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
return false;
}
/* Check ELF architecture, which is 32-bit/x86 right now
* Should change this for 64-bit if Valve gets their act together
*/
if (file->e_ident[EI_CLASS] != ELFCLASS32 || file->e_machine != EM_386 || file->e_ident[EI_DATA] != ELFDATA2LSB)
/* Check ELF endianness */
if (file->e_ident[EI_DATA] != ELFDATA2LSB)
{
return false;
}
/* Check ELF architecture */
if (file->e_ident[EI_CLASS] != ELF_CLASS || file->e_machine != ELF_MACHINE)
{
return false;
}
@ -530,11 +550,11 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
}
phdrCount = file->e_phnum;
phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff);
phdr = reinterpret_cast<ElfPHeader *>(baseAddr + file->e_phoff);
for (uint16_t i = 0; i < phdrCount; i++)
{
Elf32_Phdr &hdr = phdr[i];
ElfPHeader &hdr = phdr[i];
/* We only really care about the segment with executable code */
if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X|PF_R))
@ -553,9 +573,25 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#elif defined PLATFORM_APPLE
#ifdef PLATFORM_X86
typedef struct mach_header MachHeader;
typedef struct segment_command MachSegment;
const uint32_t MACH_MAGIC = MH_MAGIC;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT;
const cpu_type_t MACH_CPU_TYPE = CPU_TYPE_I386;
const cpu_subtype_t MACH_CPU_SUBTYPE = CPU_SUBTYPE_I386_ALL;
#else
typedef struct mach_header_64 MachHeader;
typedef struct segment_command_64 MachSegment;
const uint32_t MACH_MAGIC = MH_MAGIC_64;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT_64;
const cpu_type_t MACH_CPU_TYPE = CPU_TYPE_X86_64;
const cpu_subtype_t MACH_CPU_SUBTYPE = CPU_SUBTYPE_X86_64_ALL;
#endif
Dl_info info;
struct mach_header *file;
struct segment_command *seg;
MachHeader *file;
MachSegment *seg;
uint32_t cmd_count;
if (!dladdr(libPtr, &info))
@ -570,16 +606,16 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
/* This is for our insane sanity checks :o */
baseAddr = (uintptr_t)info.dli_fbase;
file = (struct mach_header *)baseAddr;
file = (MachHeader *)baseAddr;
/* Check Mach-O magic */
if (file->magic != MH_MAGIC)
if (file->magic != MACH_MAGIC)
{
return false;
}
/* Check architecture (32-bit/x86) */
if (file->cputype != CPU_TYPE_I386 || file->cpusubtype != CPU_SUBTYPE_I386_ALL)
/* Check architecture */
if (file->cputype != MACH_CPU_TYPE || file->cpusubtype != MACH_CPU_SUBTYPE)
{
return false;
}
@ -591,17 +627,17 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
}
cmd_count = file->ncmds;
seg = (struct segment_command *)(baseAddr + sizeof(struct mach_header));
seg = (MachSegment *)(baseAddr + sizeof(MachHeader));
/* Add up memory sizes of mapped segments */
for (uint32_t i = 0; i < cmd_count; i++)
{
if (seg->cmd == LC_SEGMENT)
if (seg->cmd == MACH_LOADCMD_SEGMENT)
{
lib.memorySize += seg->vmsize;
}
seg = (struct segment_command *)((uintptr_t)seg + seg->cmdsize);
seg = (MachSegment *)((uintptr_t)seg + seg->cmdsize);
}
#endif

View File

@ -0,0 +1,169 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2017 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 <http://www.gnu.org/licenses/>.
*
* 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 <http://www.sourcemod.net/license.php>.
*/
#include "PseudoAddrManager.h"
#ifdef PLATFORM_APPLE
#include <mach/mach.h>
#include <mach/vm_region.h>
#endif
#ifdef PLATFORM_LINUX
#include <inttypes.h>
#endif
PseudoAddressManager::PseudoAddressManager() : m_NumEntries(0)
{
}
// A pseudo address consists of a table index in the upper 6 bits and an offset in the
// lower 26 bits. The table consists of memory allocation base addresses.
void *PseudoAddressManager::FromPseudoAddress(uint32_t paddr)
{
#ifdef PLATFORM_X64
uint8_t index = paddr >> PSEUDO_OFFSET_BITS;
uint32_t offset = paddr & ((1 << PSEUDO_OFFSET_BITS) - 1);
if (index >= m_NumEntries)
return nullptr;
return reinterpret_cast<void *>(uintptr_t(m_AllocBases[index]) + offset);
#else
return nullptr;
#endif
}
uint32_t PseudoAddressManager::ToPseudoAddress(void *addr)
{
#ifdef PLATFORM_X64
uint8_t index = 0;
uint32_t offset = 0;
bool hasEntry = false;
void *base = GetAllocationBase(addr);
if (base) {
for (int i = 0; i < m_NumEntries; i++) {
if (m_AllocBases[i] == base) {
index = i;
hasEntry = true;
break;
}
}
} else {
return 0;
}
if (!hasEntry) {
index = m_NumEntries;
if (m_NumEntries < SM_ARRAYSIZE(m_AllocBases))
m_AllocBases[m_NumEntries++] = base;
else
return 0; // Table is full
}
ptrdiff_t diff = uintptr_t(addr) - uintptr_t(base);
// Ensure difference fits in 26 bits
if (diff > (UINT32_MAX >> PSEUDO_INDEX_BITS))
return 0;
return (index << PSEUDO_OFFSET_BITS) | diff;
#else
return 0;
#endif
}
void *PseudoAddressManager::GetAllocationBase(void *ptr)
{
#if defined PLATFORM_WINDOWS
MEMORY_BASIC_INFORMATION info;
if (!VirtualQuery(ptr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
return nullptr;
return info.AllocationBase;
#elif defined PLATFORM_APPLE
#ifdef PLATFORM_X86
typedef vm_region_info_t mach_vm_region_info_t;
typedef vm_region_basic_info_data_t mach_vm_region_basic_info_data_t;
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO;
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT;
#define mach_vm_region vm_region
#elif defined PLATFORM_X64
typedef vm_region_info_64_t mach_vm_region_info_t ;
typedef vm_region_basic_info_data_64_t mach_vm_region_basic_info_data_t;
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO_64;
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT_64;
#define mach_vm_region vm_region_64
#endif
vm_size_t size;
vm_address_t vmaddr = reinterpret_cast<vm_address_t>(ptr);
mach_vm_region_basic_info_data_t info;
memory_object_name_t obj;
vm_region_flavor_t flavor = MACH_VM_REGION_BASIC_INFO;
mach_msg_type_number_t count = MACH_VM_REGION_BASIC_INFO_COUNT;
kern_return_t kr = mach_vm_region(mach_task_self(), &vmaddr, &size, flavor,
reinterpret_cast<mach_vm_region_info_t>(&info),
&count, &obj);
if (kr != KERN_SUCCESS)
return nullptr;
return reinterpret_cast<void *>(vmaddr);
#elif defined PLATFORM_LINUX
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
// Format:
// lower upper prot stuff path
// 08048000-0804c000 r-xp 00000000 03:03 1010107 /bin/cat
FILE *fp = fopen("/proc/self/maps", "r");
if (fp) {
uintptr_t lower, upper;
while (fscanf(fp, "%" PRIxPTR "-%" PRIxPTR, &lower, &upper) != EOF) {
if (addr >= lower && addr <= upper) {
fclose(fp);
return reinterpret_cast<void *>(lower);
}
// Read to end of line
int c;
while ((c = fgetc(fp)) != '\n') {
if (c == EOF)
break;
}
if (c == EOF)
break;
}
fclose(fp);
}
return nullptr;
#endif
}

View File

@ -0,0 +1,51 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2017 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 <http://www.gnu.org/licenses/>.
*
* 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 <http://www.sourcemod.net/license.php>.
*/
#ifndef _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
#define _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
#include "common_logic.h"
class PseudoAddressManager
{
public:
PseudoAddressManager();
public:
void *FromPseudoAddress(uint32_t paddr);
uint32_t ToPseudoAddress(void *addr);
private:
void *GetAllocationBase(void *ptr);
private:
static constexpr uint8_t PSEUDO_OFFSET_BITS = 26;
static constexpr uint8_t PSEUDO_INDEX_BITS = sizeof(uint32_t) * 8 - PSEUDO_OFFSET_BITS;
void *m_AllocBases[1 << PSEUDO_INDEX_BITS];
uint8_t m_NumEntries;
};
#endif // _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_

View File

@ -86,6 +86,9 @@ IScriptManager *scripts = &g_PluginSys;
IExtensionSys *extsys = &g_Extensions;
ILogger *logger = &g_Logger;
CNativeOwner g_CoreNatives;
#ifdef PLATFORM_X64
PseudoAddressManager pseudoAddr;
#endif
static void AddCorePhraseFile(const char *filename)
{
@ -115,6 +118,24 @@ static void RegisterProfiler(IProfilingTool *tool)
g_ProfileToolManager.RegisterTool(tool);
}
static void *FromPseudoAddress(uint32_t paddr)
{
#ifdef PLATFORM_X64
return pseudoAddr.FromPseudoAddress(paddr);
#else
return nullptr;
#endif
}
static uint32_t ToPseudoAddress(void *addr)
{
#ifdef PLATFORM_X64
return pseudoAddr.ToPseudoAddress(addr);
#else
return 0;
#endif
}
// Defined in smn_filesystem.cpp.
extern bool OnLogPrint(const char *msg);
@ -150,6 +171,8 @@ static sm_logic_t logic =
CDataPack::Free,
CellArray::New,
CellArray::Free,
FromPseudoAddress,
ToPseudoAddress,
&g_PluginSys,
&g_ShareSys,
&g_Extensions,

View File

@ -33,6 +33,9 @@
#define _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_
#include "../sm_globals.h"
#ifdef PLATFORM_X64
#include "PseudoAddrManager.h"
#endif
namespace SourceMod {
class CoreProvider;
@ -57,6 +60,7 @@ class IVEngineServerBridge;
#endif
} // namespace SourceMod
struct ServerGlobals;
class PseudoAddressManager;
extern SourceMod::CoreProvider *bridge;
extern SourceMod::IHandleSys *handlesys;
@ -76,6 +80,7 @@ extern SourceMod::IScriptManager *scripts;
extern SourceMod::IExtensionSys *extsys;
extern SourceMod::ILogger *logger;
extern SourceMod::IMenuManager *menus;
extern PseudoAddressManager pseudoAddr;
#if defined SM_LOGIC
extern SourceMod::IVEngineServerBridge *engine;

View File

@ -708,7 +708,11 @@ enum NumberType
static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
if (addr == NULL)
{
@ -736,7 +740,11 @@ static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
if (addr == NULL)
{

View File

@ -152,7 +152,11 @@ static cell_t smn_GameConfGetAddress(IPluginContext *pCtx, const cell_t *params)
if (!gc->GetAddress(key, &val))
return 0;
#ifdef PLATFORM_X86
return (cell_t)val;
#else
return pseudoAddr.ToPseudoAddress(val);
#endif
}
static GameConfigsNatives s_GameConfigsNatives;

View File

@ -653,7 +653,7 @@ void CoreProviderImpl::InitializeBridge()
char path[PLATFORM_MAX_PATH];
ke::path::Format(path, sizeof(path),
"%s/bin/matchmaking_ds%s.%s",
"%s/bin/" PLATFORM_FOLDER "matchmaking_ds%s.%s",
g_SMAPI->GetBaseDir(),
MATCHMAKINGDS_SUFFIX,
MATCHMAKINGDS_EXT);
@ -691,7 +691,7 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
/* Now it's time to load the logic binary */
g_SMAPI->PathFormat(file,
sizeof(file),
"%s/bin/sourcemod.logic." PLATFORM_LIB_EXT,
"%s/bin/" PLATFORM_ARCH_FOLDER "sourcemod.logic." PLATFORM_LIB_EXT,
g_SourceMod.GetSourceModPath());
char myerror[255];

View File

@ -2609,7 +2609,12 @@ static cell_t GetEntityAddress(IPluginContext *pContext, const cell_t *params)
{
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
}
#ifdef PLATFORM_X86
return reinterpret_cast<cell_t>(pEntity);
#else
return g_SourceMod.ToPseudoAddress(pEntity);
#endif
}
REGISTER_NATIVES(entityNatives)

View File

@ -185,7 +185,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
/* Attempt to load the JIT! */
char file[PLATFORM_MAX_PATH];
char myerror[255];
g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s",
g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/" PLATFORM_ARCH_FOLDER "sourcepawn.jit.x86.%s",
GetSourceModPath(),
PLATFORM_LIB_EXT
);
@ -195,7 +195,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
{
if (error && maxlength)
{
ke::SafeSprintf(error, maxlength, "%s (failed to load bin/sourcepawn.jit.x86.%s)",
ke::SafeSprintf(error, maxlength, "%s (failed to load bin/" PLATFORM_ARCH_FOLDER "sourcepawn.jit.x86.%s)",
myerror,
PLATFORM_LIB_EXT);
}
@ -745,6 +745,16 @@ bool SourceModBase::IsMapRunning()
return g_OnMapStarted;
}
void *SourceModBase::FromPseudoAddress(uint32_t pseudoAddr)
{
return logicore.FromPseudoAddress(pseudoAddr);
}
uint32_t SourceModBase::ToPseudoAddress(void *addr)
{
return logicore.ToPseudoAddress(addr);
}
class ConVarRegistrar :
public IConCommandBaseAccessor,
public SMGlobalClass

View File

@ -135,6 +135,8 @@ public: // ISourceMod
int GetPluginId();
int GetShApiVersion();
bool IsMapRunning();
void *FromPseudoAddress(uint32_t pseudoAddr);
uint32_t ToPseudoAddress(void *addr);
private:
void ShutdownServices();
private:

View File

@ -1,27 +1,30 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'bintools.ext')
binary.compiler.defines += ['HOOKING_ENABLED']
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
os.path.join(builder.sourcePath, 'public', 'jit'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'bintools.ext', arch)
binary.compiler.defines += ['HOOKING_ENABLED']
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
os.path.join(builder.sourcePath, 'public', 'jit'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
'CallMaker.cpp',
'CallWrapper.cpp',
'HookWrapper.cpp',
'jit_call.cpp',
'jit_hook.cpp',
'../../public/smsdk_ext.cpp'
]
binary.sources += [
'extension.cpp',
'CallMaker.cpp',
'CallWrapper.cpp',
'../../public/smsdk_ext.cpp'
]
SM.extensions += [builder.Add(binary)]
if arch == 'x64':
binary.sources += ['jit_call_x64.cpp']
else:
binary.sources += ['jit_call.cpp']
SM.extensions += [builder.Add(binary)]

View File

@ -82,7 +82,8 @@ ICallWrapper *CallMaker::CreateCall(void *address,
CallConvention cv,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams)
unsigned int numParams,
unsigned int fnFlags)
{
SourceHook::CProtoInfoBuilder protoInfo(GetSHCallConvention(cv));
@ -103,7 +104,11 @@ ICallWrapper *CallMaker::CreateCall(void *address,
NULL, NULL, NULL, NULL);
}
#if defined PLATFORM_X64
return g_CallMaker2.CreateCall(address, &(*protoInfo), retInfo, paramInfo, fnFlags);
#else
return g_CallMaker2.CreateCall(address, &(*protoInfo));
#endif
}
ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
@ -111,7 +116,8 @@ ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
unsigned int thisOffs,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams)
unsigned int numParams,
unsigned int fnFlags)
{
SourceHook::MemFuncInfo info;
info.isVirtual = true;
@ -138,12 +144,16 @@ ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
NULL, NULL, NULL, NULL);
}
#if defined PLATFORM_X64
return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info, retInfo, paramInfo, fnFlags);
#else
return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info);
#endif
}
ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo)
{
#ifdef PLATFORM_X86
CallWrapper *pWrapper = new CallWrapper(protoInfo);
pWrapper->SetCalleeAddr(address);
@ -151,11 +161,15 @@ ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo
pWrapper->SetCodeBaseAddr(addr);
return pWrapper;
#else
return nullptr;
#endif
}
ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info)
{
#ifdef PLATFORM_X86
CallWrapper *pWrapper = new CallWrapper(protoInfo);
pWrapper->SetMemFuncInfo(info);
@ -163,9 +177,48 @@ ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoIn
pWrapper->SetCodeBaseAddr(addr);
return pWrapper;
#else
return nullptr;
#endif
}
#if defined HOOKING_ENABLED
ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo,
const PassInfo *retInfo, const PassInfo paramInfo[],
unsigned int fnFlags)
{
#ifdef PLATFORM_X64
CallWrapper *pWrapper = new CallWrapper(protoInfo, retInfo, paramInfo, fnFlags);
pWrapper->SetCalleeAddr(address);
void *addr = JIT_CallCompile(pWrapper, FuncAddr_Direct);
pWrapper->SetCodeBaseAddr(addr);
return pWrapper;
#else
return nullptr;
#endif
}
ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int fnFlags)
{
#ifdef PLATFORM_X64
CallWrapper *pWrapper = new CallWrapper(protoInfo, retInfo, paramInfo, fnFlags);
pWrapper->SetMemFuncInfo(info);
void *addr = JIT_CallCompile(pWrapper, FuncAddr_VTable);
pWrapper->SetCodeBaseAddr(addr);
return pWrapper;
#else
return nullptr;
#endif
}
#if 0
IHookWrapper *CallMaker2::CreateVirtualHook(SourceHook::ISourceHook *pSH,
const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info,

View File

@ -34,7 +34,6 @@
#include "CallWrapper.h"
#include "HookWrapper.h"
using namespace SourceMod;
@ -45,26 +44,30 @@ public: //IBinTools
CallConvention cv,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams);
unsigned int numParams,
unsigned int fnFlags);
ICallWrapper *CreateVCall(unsigned int vtblIdx,
unsigned int vtblOffs,
unsigned int thisOffs,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams);
unsigned int numParams,
unsigned int fnFlags);
};
class CallMaker2
#if defined HOOKING_ENABLED
: public IBinTools2
#endif
{
public: //IBinTools2
virtual ICallWrapper *CreateCall(void *address,
const SourceHook::ProtoInfo *protoInfo);
virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info);
#if defined HOOKING_ENABLED
ICallWrapper *CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo,
const PassInfo *retInfo, const PassInfo paramInfo[], unsigned int fnFlags);
ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info, const PassInfo *retInfo,
const PassInfo paramInfo[], unsigned int fnFlags);
#if 0
virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH,
const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info,

View File

@ -33,7 +33,7 @@
#include "CallWrapper.h"
#include "CallMaker.h"
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo)
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo) : m_FnFlags(0)
{
m_AddrCodeBase = NULL;
m_AddrCallee = NULL;
@ -77,6 +77,22 @@ CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo)
}
}
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo, const PassInfo *retInfo,
const PassInfo paramInfo[], unsigned int fnFlags) : CallWrapper(protoInfo)
{
m_RetParam->fields = retInfo->fields;
m_RetParam->numFields = retInfo->numFields;
unsigned int argnum = protoInfo->numOfParams;
for (unsigned int i = 0; i < argnum; i++)
{
m_Params[i].info.fields = paramInfo[i].fields;
m_Params[i].info.numFields = paramInfo[i].numFields;
}
m_FnFlags = fnFlags;
}
CallWrapper::~CallWrapper()
{
delete [] m_Params;
@ -184,3 +200,8 @@ unsigned int CallWrapper::GetParamOffset(unsigned int num)
return m_Params[num].offset;
}
unsigned int CallWrapper::GetFunctionFlags()
{
return m_FnFlags;
}

View File

@ -47,6 +47,8 @@ class CallWrapper : public ICallWrapper
{
public:
CallWrapper(const SourceHook::ProtoInfo *protoInfo);
CallWrapper(const SourceHook::ProtoInfo *protoInfo, const PassInfo *retInfo,
const PassInfo paramInfo[], unsigned int fnFlags);
~CallWrapper();
public: //ICallWrapper
CallConvention GetCallConvention();
@ -59,6 +61,7 @@ public: //ICallWrapper
SourceHook::ProtoInfo::CallConvention GetSHCallConvention();
const SourceHook::PassInfo *GetSHParamInfo(unsigned int num);
unsigned int GetParamOffset(unsigned int num);
unsigned int GetFunctionFlags();
public:
void SetCalleeAddr(void *addr);
void SetCodeBaseAddr(void *addr);
@ -74,6 +77,7 @@ private:
void *m_AddrCallee;
void *m_AddrCodeBase;
SourceHook::MemFuncInfo m_FuncInfo;
unsigned int m_FnFlags;
};
#endif //_INCLUDE_SOURCEMOD_CALLWRAPPER_H_

View File

@ -50,12 +50,6 @@ bool BinTools::SDK_OnLoad(char *error, size_t maxlength, bool late)
g_SPEngine = g_pSM->GetScriptingEngine();
g_pShareSys->AddInterface(myself, &g_CallMaker);
/* IBinTools2 is only compatible with SH v5 */
if (g_pSM->GetShApiVersion() >= 5)
{
g_pShareSys->AddInterface(myself, &g_CallMaker2);
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -34,11 +34,12 @@
#include <jit_helpers.h>
#include <x86_macros.h>
#include <sm_platform.h>
#include "CallWrapper.h"
#include "HookWrapper.h"
void *JIT_CallCompile(CallWrapper *pWrapper, FuncAddrMethod method);
#if defined HOOKING_ENABLED
#if 0
void *JIT_HookCompile(HookWrapper *pWrapper);
void JIT_FreeHook(void *addr);
#endif

View File

@ -214,7 +214,7 @@ inline void Write_Push_Params(JitWriter *jit,
IA32_Push_Reg(jit, kREG_EBX);
//push <pWrapper>
IA32_Push_Imm32(jit, (jit_int32_t)pWrapper);
IA32_Push_Imm32(jit, (jit_int32_t)(intptr_t)pWrapper);
}
inline void Write_Call_Handler(JitWriter *jit, void *addr)

View File

@ -0,0 +1,656 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod BinTools Extension
* Copyright (C) 2004-2017 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 <http://www.gnu.org/licenses/>.
*
* 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 <http://www.sourcemod.net/license.php>.
*/
#include <jit_helpers.h>
#include <x86_macros.h>
// 64-bit registers
const jit_uint8_t kREG_RAX = kREG_EAX;
const jit_uint8_t kREG_RCX = kREG_ECX;
const jit_uint8_t kREG_RDX = kREG_EDX;
const jit_uint8_t kREG_RBX = kREG_EBX;
const jit_uint8_t kREG_RSP = kREG_ESP;
const jit_uint8_t kREG_RBP = kREG_EBP;
const jit_uint8_t kREG_RSI = kREG_ESI;
const jit_uint8_t kREG_RDI = kREG_EDI;
const jit_uint8_t kREG_R8 = 8;
const jit_uint8_t kREG_R9 = 9;
const jit_uint8_t kREG_R10 = 10;
const jit_uint8_t kREG_R11 = 11;
const jit_uint8_t kREG_R12 = 12;
const jit_uint8_t kREG_R13 = 13;
const jit_uint8_t kREG_R14 = 14;
const jit_uint8_t kREG_R15 = 15;
const jit_uint8_t kREG_XMM0 = 0;
const jit_uint8_t kREG_XMM1 = 1;
const jit_uint8_t kREG_XMM2 = 2;
const jit_uint8_t kREG_XMM3 = 3;
const jit_uint8_t kREG_XMM4 = 4;
const jit_uint8_t kREG_XMM5 = 5;
const jit_uint8_t kREG_XMM6 = 6;
const jit_uint8_t kREG_XMM7 = 7;
const jit_uint8_t kREG_XMM8 = 8;
const jit_uint8_t kREG_XMM9 = 9;
const jit_uint8_t kREG_XMM10 = 10;
const jit_uint8_t kREG_XMM11 = 11;
const jit_uint8_t kREG_XMM12 = 12;
const jit_uint8_t kREG_XMM13 = 13;
const jit_uint8_t kREG_XMM14 = 14;
const jit_uint8_t kREG_XMM15 = 15;
#define X64_REX_PREFIX 0x40
#define IA32_MOV_REG8_IMM8 0xB0
inline jit_uint8_t x64_rex(bool w, jit_uint8_t r, jit_uint8_t x, jit_uint8_t b)
{
return (X64_REX_PREFIX | ((jit_uint8_t)w << 3) | ((r>>3) << 2) | ((x>>3) << 1) | (b >> 3));
}
inline void X64_Push_Reg(JitWriter *jit, jit_uint8_t reg)
{
if (reg >= kREG_R8)
jit->write_ubyte(x64_rex(false, 0, 0, reg));
IA32_Push_Reg(jit, reg & 7);
}
inline void X64_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Mov_Reg_Rm(jit, dest & 7, src & 7, mode);
}
inline void X64_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Mov_Reg_Rm_Disp8(jit, dest & 7, src & 7, disp);
}
inline void X64_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Mov_Reg_Rm_Disp32(jit, dest & 7, src & 7, disp);
}
inline void X64_Mov_Reg32_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
if (src>= kREG_R8 || dest >= kREG_R8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
IA32_Mov_Reg_Rm(jit, dest & 7, src & 7, mode);
}
inline void X64_Mov_Reg32_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (src>= kREG_R8 || dest >= kREG_R8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
IA32_Mov_Reg_Rm_Disp8(jit, dest & 7, src & 7, disp);
}
inline void X64_Mov_Reg32_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (src>= kREG_R8 || dest >= kREG_R8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
IA32_Mov_Reg_Rm_Disp32(jit, dest & 7, src & 7, disp);
}
inline void X64_And_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
{
jit->write_ubyte(x64_rex(true, 0, 0, reg));
IA32_And_Rm_Imm8(jit, reg & 7, mode, value);
}
inline void X64_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, 5, 0, reg));
IA32_Sub_Rm_Imm8(jit, reg & 7, val, mode);
}
inline void X64_Sub_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, 5, 0, reg));
IA32_Sub_Rm_Imm32(jit, reg & 7, val, mode);
}
inline void X64_Pop_Reg(JitWriter *jit, jit_uint8_t reg)
{
if (reg >= kREG_R8)
jit->write_ubyte(x64_rex(false, 0, 0, reg));
IA32_Pop_Reg(jit, reg & 7);
}
inline void X64_Return(JitWriter *jit)
{
IA32_Return(jit);
}
inline void X64_Movzx_Reg64_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm8_Disp8(jit, dest & 7, src & 7, disp);
}
inline void X64_Movzx_Reg64_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm8(jit, dest & 7, src & 7, mode);
}
inline void X64_Movzx_Reg64_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm8_Disp32(jit, dest & 7, src & 7, disp);
}
inline void X64_Mov_RmRSP_Reg(JitWriter *jit, jit_uint8_t src)
{
jit->write_ubyte(x64_rex(true, kREG_RSP, 0, src));
jit->write_ubyte(IA32_MOV_RM_REG);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, kREG_RSP));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
}
inline void X64_Mov_RmRSP_Disp8_Reg(JitWriter *jit, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, src, 0, kREG_RSP));
jit->write_ubyte(IA32_MOV_RM_REG);
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, kREG_RSP));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
jit->write_byte(disp);
}
inline void X64_Mov_RmRSP_Disp32_Reg(JitWriter *jit, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, src, 0, kREG_RSP));
jit->write_ubyte(IA32_MOV_RM_REG);
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, kREG_RSP));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
jit->write_byte(disp);
}
inline void X64_Movzx_Reg64_Rm16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm16(jit, dest & 7, src & 7, mode);
}
inline void X64_Movzx_Reg64_Rm16_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm16_Disp8(jit, dest & 7, src & 7, disp);
}
inline void X64_Movzx_Reg64_Rm16_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm16_Disp32(jit, dest & 7, src & 7, disp);
}
inline void X64_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val)
{
jit->write_ubyte(x64_rex(true, dest, 0, src_base));
IA32_Lea_DispRegImm8(jit, dest & 7, src_base & 7, val);
}
inline void X64_Lea_DispRegImm32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val)
{
jit->write_ubyte(x64_rex(true, dest, 0, src_base));
IA32_Lea_DispRegImm32(jit, dest & 7, src_base & 7, val);
}
inline void X64_Add_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t value, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, 0, 0, reg));
IA32_Add_Rm_Imm8(jit, reg & 7, value, mode);
}
inline void X64_Add_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, 0, 0, reg));
IA32_Add_Rm_Imm32(jit, reg & 7, value, mode);
}
inline void X64_Movaps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movups_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movaps_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x29);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
}
inline void X64_Movapd_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
jit->write_ubyte(0x66);
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x29);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
}
inline void X64_Movups_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
}
inline void X64_Movupd_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
jit->write_ubyte(0x66);
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
}
inline void X64_Movupd_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(0x66);
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movaps_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x29);
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movups_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movaps_Rm_Disp32_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x29);
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movups_Rm_Disp32_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movlps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x12);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movhps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x16);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movaps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movups_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movlps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x12);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movhps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x16);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movaps_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movups_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movapd_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movupd_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movapd_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movupd_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movapd_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movupd_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Cld(JitWriter *jit)
{
IA32_Cld(jit);
}
inline void X64_Rep(JitWriter *jit)
{
IA32_Rep(jit);
}
inline void X64_Movsq(JitWriter *jit)
{
jit->write_ubyte(x64_rex(true, 0, 0, 0));
jit->write_ubyte(IA32_MOVSD);
}
inline void X64_Movsb(JitWriter *jit)
{
jit->write_ubyte(IA32_MOVSB);
}
inline void X64_Lea_Reg_DispRegMultImm8(JitWriter *jit,
jit_uint8_t dest,
jit_uint8_t src_base,
jit_uint8_t src_index,
jit_uint8_t scale,
jit_int8_t val)
{
jit->write_ubyte(x64_rex(true, dest, 0, src_index));
IA32_Lea_Reg_DispRegMultImm8(jit, dest & 7, src_base, src_index & 7, scale, val);
}
inline void X64_Lea_Reg_DispRegMultImm32(JitWriter *jit,
jit_uint8_t dest,
jit_uint8_t src_base,
jit_uint8_t src_index,
jit_uint8_t scale,
jit_int32_t val)
{
jit->write_ubyte(x64_rex(true, dest, 0, src_index));
jit->write_ubyte(IA32_LEA_REG_MEM);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, kREG_SIB));
jit->write_ubyte(ia32_sib(scale, src_index & 7, src_base));
jit->write_int32(val);
}
inline jitoffs_t X64_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t num)
{
jitoffs_t offs;
jit->write_ubyte(x64_rex(true, 0, 0, dest));
jit->write_ubyte(0xC7);
jit->write_ubyte(ia32_modrm(MOD_REG, 0, dest & 7));
offs = jit->get_outputpos();
jit->write_int32(num);
return offs;
}
inline jitoffs_t X64_Mov_Reg_Imm64(JitWriter *jit, jit_uint8_t dest, jit_int64_t num)
{
jitoffs_t offs;
jit->write_ubyte(x64_rex(true, 0, 0, dest));
jit->write_ubyte(IA32_MOV_REG_IMM+(dest & 7));
offs = jit->get_outputpos();
jit->write_int64(num);
return offs;
}
inline void X64_Mov_Rm8_Reg8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
if (dest >= kREG_R8 || src > kREG_R8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(IA32_MOV_RM8_REG8);
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
mode = MOD_DISP8;
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
else if ((dest & 7) == kREG_RBP)
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
}
inline void X64_Mov_Rm32_Reg32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
if (dest >= kREG_R8 || src > kREG_R8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(IA32_MOV_RM_REG);
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
mode = MOD_DISP8;
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
else if ((dest & 7) == kREG_RBP)
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
}
inline void X64_Mov_Rm16_Reg16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(IA32_16BIT_PREFIX);
X64_Mov_Rm32_Reg32(jit, dest, src, mode);
}
inline void X64_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, src, 0, dest));
jit->write_ubyte(IA32_MOV_RM_REG);
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
mode = MOD_DISP8;
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
else if ((dest & 7) == kREG_RBP)
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
}
inline void X64_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, src, 0, dest));
IA32_Mov_Rm_Reg_Disp8(jit, dest & 7, src & 7, disp);
}
inline jitoffs_t X64_Call_Imm32(JitWriter *jit, jit_int32_t disp)
{
return IA32_Call_Imm32(jit, disp);
}
inline void X64_Write_Jump32_Abs(JitWriter *jit, jitoffs_t jmp, void *target)
{
IA32_Write_Jump32_Abs(jit, jmp, target);
}
inline void X64_Call_Reg(JitWriter *jit, jit_uint8_t reg)
{
if (reg >= kREG_R8)
jit->write_ubyte(x64_rex(false, 0, 0, reg));
IA32_Call_Reg(jit, reg & 7);
}
inline jitoffs_t X64_Mov_Reg8_Imm8(JitWriter *jit, jit_uint8_t dest, jit_int8_t value)
{
jitoffs_t offs;
if (dest >= kREG_R8)
jit->write_ubyte(x64_rex(false, 0, 0, dest));
jit->write_ubyte(IA32_MOV_REG8_IMM8+(dest & 7));
offs = jit->get_outputpos();
jit->write_byte(value);
return offs;
}
inline void X64_Movd_Reg32_Xmm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
jit->write_ubyte(0x66);
if (dest >= kREG_R8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x7E);
jit->write_ubyte(ia32_modrm(MOD_REG, src & 7, dest & 7));
}
inline void X64_Movq_Reg_Xmm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
jit->write_ubyte(0x66);
jit->write_ubyte(x64_rex(true, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x7E);
jit->write_ubyte(ia32_modrm(MOD_REG, src & 7, dest & 7));
}

View File

@ -1,23 +1,24 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'clientprefs.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'clientprefs.ext', arch)
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
'cookie.cpp',
'menus.cpp',
'natives.cpp',
'query.cpp',
'../../public/smsdk_ext.cpp'
]
binary.sources += [
'extension.cpp',
'cookie.cpp',
'menus.cpp',
'natives.cpp',
'query.cpp',
'../../public/smsdk_ext.cpp'
]
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]

View File

@ -11,14 +11,24 @@ project.sources += [
'util_cstrike.cpp',
'../../public/smsdk_ext.cpp',
'../../public/CDetour/detours.cpp',
'../../public/asm/asm.c'
'../../public/asm/asm.c',
'../../public/libudis86/decode.c',
'../../public/libudis86/itab.c',
'../../public/libudis86/syn-att.c',
'../../public/libudis86/syn-intel.c',
'../../public/libudis86/syn.c',
'../../public/libudis86/udis86.c',
]
project.compiler.defines += ['HAVE_STRING_H'];
for sdk_name in ['css', 'csgo']:
if sdk_name not in SM.sdks:
continue
sdk = SM.sdks[sdk_name]
for arch in SM.archs:
if not arch in sdk.platformSpec[builder.target.platform]:
continue
SM.HL2Config(project, 'game.cstrike.ext.' + sdk.ext, sdk)
SM.HL2Config(project, 'game.cstrike.ext.' + sdk.ext, sdk, arch)
SM.extensions += builder.Add(project)

View File

@ -18,7 +18,11 @@ struct HashItemDef_Node
class CHashItemDef
{
public:
#ifdef PLATFORM_X86
unsigned char padding[36];
#else
unsigned char padding[56];
#endif
HashItemDef_Node *pMem;
int nAllocatedCount;
int nGrowSize;

View File

@ -192,9 +192,9 @@ CEconItemSchema *GetItemSchema()
void *pSchema = NULL;
pWrapper->Execute(NULL, &pSchema);
//In windows this is actually ItemSystem() + 4 is ItemSchema
#ifdef WIN32
return (CEconItemSchema *)((intptr_t)pSchema + 4);
//On windows/mac this is actually ItemSystem() + sizeof(void *) is ItemSchema
#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_APPLE)
return (CEconItemSchema *)((intptr_t)pSchema + sizeof(void *));
#else
return (CEconItemSchema *)pSchema;
#endif

View File

@ -2,27 +2,27 @@
import os
libcurl = builder.Build('curl-src/lib/AMBuilder')
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'webternet.ext', arch)
binary.compiler.includes += [
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'include')
]
binary.compiler.defines += ['CURL_STATICLIB']
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.compiler.postlink += [libcurl[arch].binary]
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-lrt']
elif builder.target.platform == 'windows':
binary.compiler.postlink += ['ws2_32.lib']
binary = SM.ExtLibrary(builder, 'webternet.ext')
binary.compiler.includes += [
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'include')
]
binary.compiler.defines += ['CURL_STATICLIB']
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.compiler.postlink += [libcurl.binary]
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-lrt']
elif builder.target.platform == 'windows':
binary.compiler.postlink += ['ws2_32.lib']
binary.sources += [
'extension.cpp',
'curlapi.cpp',
'../../public/smsdk_ext.cpp'
]
binary.sources += [
'extension.cpp',
'curlapi.cpp',
'../../public/smsdk_ext.cpp'
]
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]

View File

@ -3,96 +3,98 @@ import os, platform
builder.SetBuildFolder('libcurl')
binary = SM.StaticLibrary(builder, 'curl')
binary.compiler.includes += [
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'lib'),
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'include')
]
if builder.target.platform == 'mac':
mac_version, ignore, ignore = platform.mac_ver()
mac_tuple = mac_version.split('.')
if int(mac_tuple[0]) >= 10 and int(mac_tuple[1]) >= 9:
binary.compiler.defines += ['BUILTIN_STRLCAT']
elif builder.target.platform == 'windows':
binary.compiler.defines += [
'BUILDING_LIBCURL',
'CURL_STATICLIB',
'CURL_DISABLE_LDAP',
rvalue = {}
for arch in SM.archs:
binary = SM.StaticLibrary(builder, 'curl', arch)
binary.compiler.includes += [
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'lib'),
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'include')
]
elif builder.target.platform == 'linux':
binary.compiler.defines += ['_GNU_SOURCE']
if binary.compiler.family == 'clang':
# https://llvm.org/bugs/show_bug.cgi?id=16428
binary.compiler.cflags += ['-Wno-attributes']
if builder.target.platform == 'mac':
mac_version, ignore, ignore = platform.mac_ver()
mac_tuple = mac_version.split('.')
if int(mac_tuple[0]) >= 10 and int(mac_tuple[1]) >= 9:
binary.compiler.defines += ['BUILTIN_STRLCAT']
elif builder.target.platform == 'windows':
binary.compiler.defines += [
'BUILDING_LIBCURL',
'CURL_STATICLIB',
'CURL_DISABLE_LDAP',
]
elif builder.target.platform == 'linux':
binary.compiler.defines += ['_GNU_SOURCE']
binary.sources += [
'base64.c',
'connect.c',
'content_encoding.c',
'cookie.c',
'curl_addrinfo.c',
'dict.c',
'easy.c',
'escape.c',
'file.c',
'formdata.c',
'ftp.c',
'getenv.c',
'getinfo.c',
'gtls.c',
'hash.c',
'hostares.c',
'hostasyn.c',
'hostip.c',
'hostip4.c',
'hostip6.c',
'hostsyn.c',
'hostthre.c',
'http.c',
'http_chunks.c',
'http_digest.c',
'http_negotiate.c',
'http_ntlm.c',
'if2ip.c',
'inet_ntop.c',
'inet_pton.c',
'krb4.c',
'krb5.c',
'ldap.c',
'llist.c',
'md5.c',
'memdebug.c',
'mprintf.c',
'multi.c',
'netrc.c',
'nss.c',
'parsedate.c',
'progress.c',
'qssl.c',
'rawstr.c',
'security.c',
'select.c',
'sendf.c',
'share.c',
'socks.c',
'speedcheck.c',
'splay.c',
'ssh.c',
'sslgen.c',
'ssluse.c',
'strdup.c',
'strequal.c',
'strerror.c',
'strtok.c',
'strtoofft.c',
'telnet.c',
'tftp.c',
'timeval.c',
'transfer.c',
'url.c',
'version.c'
]
rvalue = builder.Add(binary)
if binary.compiler.family == 'clang':
# https://llvm.org/bugs/show_bug.cgi?id=16428
binary.compiler.cflags += ['-Wno-attributes']
binary.sources += [
'base64.c',
'connect.c',
'content_encoding.c',
'cookie.c',
'curl_addrinfo.c',
'dict.c',
'easy.c',
'escape.c',
'file.c',
'formdata.c',
'ftp.c',
'getenv.c',
'getinfo.c',
'gtls.c',
'hash.c',
'hostares.c',
'hostasyn.c',
'hostip.c',
'hostip4.c',
'hostip6.c',
'hostsyn.c',
'hostthre.c',
'http.c',
'http_chunks.c',
'http_digest.c',
'http_negotiate.c',
'http_ntlm.c',
'if2ip.c',
'inet_ntop.c',
'inet_pton.c',
'krb4.c',
'krb5.c',
'ldap.c',
'llist.c',
'md5.c',
'memdebug.c',
'mprintf.c',
'multi.c',
'netrc.c',
'nss.c',
'parsedate.c',
'progress.c',
'qssl.c',
'rawstr.c',
'security.c',
'select.c',
'sendf.c',
'share.c',
'socks.c',
'speedcheck.c',
'splay.c',
'ssh.c',
'sslgen.c',
'ssluse.c',
'strdup.c',
'strequal.c',
'strerror.c',
'strtok.c',
'strtoofft.c',
'telnet.c',
'tftp.c',
'timeval.c',
'transfer.c',
'url.c',
'version.c'
]
rvalue[arch] = builder.Add(binary)

View File

@ -1,19 +1,20 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'geoip.ext')
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if builder.target.platform == 'windows':
binary.compiler.postlink += ['wsock32.lib']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'geoip.ext', arch)
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if builder.target.platform == 'windows':
binary.compiler.postlink += ['wsock32.lib']
binary.sources += [
'extension.cpp',
'GeoIP.c',
'../../public/smsdk_ext.cpp'
]
binary.sources += [
'extension.cpp',
'GeoIP.c',
'../../public/smsdk_ext.cpp'
]
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]

View File

@ -2,45 +2,46 @@
import os
if SM.mysql_root:
binary = SM.ExtLibrary(builder, 'dbi.mysql.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mysql_root, 'include'),
os.path.join(SM.mms_root, 'core', 'sourcehook')
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if builder.target.platform == 'linux' or builder.target.platform == 'mac':
binary.compiler.postlink += [
os.path.join(SM.mysql_root, 'lib', 'libmysqlclient_r.a'),
'-lz',
'-lpthread',
'-lm',
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'dbi.mysql.ext', arch)
binary.compiler.cxxincludes += [
os.path.join(SM.mysql_root[arch], 'include'),
os.path.join(SM.mms_root, 'core', 'sourcehook')
]
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-lrt']
elif builder.target.platform == 'windows':
binary.compiler.postlink += [
os.path.join(SM.mysql_root, 'lib', 'opt', 'mysqlclient.lib'),
os.path.join(SM.mysql_root, 'lib', 'opt', 'zlib.lib'),
'wsock32.lib'
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if builder.target.platform == 'linux' or builder.target.platform == 'mac':
binary.compiler.postlink += [
os.path.join(SM.mysql_root[arch], 'lib', 'libmysqlclient_r.a'),
'-lz',
'-lpthread',
'-lm',
]
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-lrt']
elif builder.target.platform == 'windows':
binary.compiler.postlink += [
os.path.join(SM.mysql_root, 'lib', 'opt', 'mysqlclient.lib'),
os.path.join(SM.mysql_root, 'lib', 'opt', 'zlib.lib'),
'wsock32.lib'
]
binary.sources += [
'../../public/smsdk_ext.cpp',
'mysql/MyBasicResults.cpp',
'mysql/MyBoundResults.cpp',
'mysql/MyDatabase.cpp',
'mysql/MyDriver.cpp',
'mysql/MyStatement.cpp',
'extension.cpp'
]
binary.sources += [
'../../public/smsdk_ext.cpp',
'mysql/MyBasicResults.cpp',
'mysql/MyBoundResults.cpp',
'mysql/MyDatabase.cpp',
'mysql/MyDriver.cpp',
'mysql/MyStatement.cpp',
'extension.cpp'
]
if binary.compiler.family == 'msvc' and binary.compiler.version >= 1900:
binary.sources += [ 'msvc15hack.c' ]
binary.compiler.linkflags += ['legacy_stdio_definitions.lib', 'legacy_stdio_wide_specifiers.lib']
if binary.compiler.family == 'msvc' and binary.compiler.version >= 1900:
binary.sources += [ 'msvc15hack.c' ]
binary.compiler.linkflags += ['legacy_stdio_definitions.lib', 'legacy_stdio_wide_specifiers.lib']
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]

View File

@ -1,28 +1,35 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'regex.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'regex.ext', arch)
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if builder.target.platform == 'linux':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_linux', 'libpcre.a')
elif builder.target.platform == 'windows':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_win', 'pcre.lib')
elif builder.target.platform == 'mac':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_darwin', 'libpcre.a')
binary.compiler.postlink += [binary.Dep(path)]
if builder.target.platform == 'linux':
if arch == 'x86':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_linux', 'libpcre.a')
elif arch == 'x64':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_linux64', 'libpcre.a')
elif builder.target.platform == 'windows':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_win', 'pcre.lib')
elif builder.target.platform == 'mac':
if arch == 'x86':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_darwin', 'libpcre.a')
elif arch == 'x64':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_darwin64', 'libpcre.a')
binary.compiler.postlink += [binary.Dep(path)]
binary.sources += [
'extension.cpp',
'CRegEx.cpp',
'../../public/smsdk_ext.cpp'
]
binary.sources += [
'extension.cpp',
'CRegEx.cpp',
'../../public/smsdk_ext.cpp'
]
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]

Binary file not shown.

Binary file not shown.

View File

@ -13,11 +13,15 @@ project.sources += [
for sdk_name in SM.sdks:
sdk = SM.sdks[sdk_name]
binary = SM.HL2Config(project, 'sdkhooks.ext.' + sdk.ext, sdk)
binary.compiler.cxxincludes += [
os.path.join(sdk.path, 'game', 'shared')
]
if binary.compiler.behavior == 'gcc':
binary.compiler.cxxflags += ['-Wno-invalid-offsetof']
for arch in SM.archs:
if not arch in sdk.platformSpec[builder.target.platform]:
continue
binary = SM.HL2Config(project, 'sdkhooks.ext.' + sdk.ext, sdk, arch)
binary.compiler.cxxincludes += [
os.path.join(sdk.path, 'game', 'shared')
]
if binary.compiler.behavior == 'gcc':
binary.compiler.cxxflags += ['-Wno-invalid-offsetof']
SM.extensions += builder.Add(project)

View File

@ -26,23 +26,34 @@ project.sources += [
'vstringtable.cpp',
'../../public/smsdk_ext.cpp',
'../../public/CDetour/detours.cpp',
'../../public/asm/asm.c'
'../../public/asm/asm.c',
'../../public/libudis86/decode.c',
'../../public/libudis86/itab.c',
'../../public/libudis86/syn-att.c',
'../../public/libudis86/syn-intel.c',
'../../public/libudis86/syn.c',
'../../public/libudis86/udis86.c',
]
project.compiler.defines += ['HAVE_STRING_H'];
for sdk_name in SM.sdks:
sdk = SM.sdks[sdk_name]
binary = SM.HL2Config(project, 'sdktools.ext.' + sdk.ext, sdk)
binary.compiler.cxxincludes += [
os.path.join(sdk.path, 'game', 'shared'),
os.path.join(builder.sourcePath, 'public', 'jit'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
]
for arch in SM.archs:
if not arch in sdk.platformSpec[builder.target.platform]:
continue
if sdk.name != 'episode1':
binary.compiler.defines += ['HOOKING_ENABLED']
binary = SM.HL2Config(project, 'sdktools.ext.' + sdk.ext, sdk, arch)
binary.compiler.cxxincludes += [
os.path.join(sdk.path, 'game', 'shared'),
os.path.join(builder.sourcePath, 'public', 'jit'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
]
if binary.compiler.behavior == 'gcc':
binary.compiler.cxxflags += ['-Wno-invalid-offsetof']
if sdk.name != 'episode1':
binary.compiler.defines += ['HOOKING_ENABLED']
if binary.compiler.behavior == 'gcc':
binary.compiler.cxxflags += ['-Wno-invalid-offsetof']
SM.extensions += builder.Add(project)

View File

@ -320,7 +320,12 @@ void TempEntityManager::Initialize()
return;
}
/* Store the head of the TE linked list */
#ifdef PLATFORM_X86
m_ListHead = **(void ***) ((unsigned char *) addr + offset);
#else
int32_t varOffset = *(int32_t *) ((unsigned char *) addr + offset);
m_ListHead = **(void ***) ((unsigned char *) addr + offset + sizeof(int32_t) + varOffset);
#endif
}
else
{

View File

@ -96,10 +96,12 @@ ValveCall *CreateValveCall(void *addr,
/* Get return information - encode only */
PassInfo retBuf;
ObjectField retFieldBuf[16];
size_t retBufSize = 0;
bool retbuf_needs_extra;
if (retInfo)
{
retBuf.fields = retFieldBuf;
if ((size = ValveParamToBinParam(retInfo->vtype, retInfo->type, retInfo->flags, &retBuf, retbuf_needs_extra)) == 0)
{
delete vc;
@ -110,12 +112,14 @@ ValveCall *CreateValveCall(void *addr,
/* Get parameter info */
PassInfo paramBuf[32];
ObjectField fieldBuf[32][16];
size_t sizes[32];
size_t normSize = 0;
size_t extraSize = 0;
for (unsigned int i=0; i<numParams; i++)
{
bool needs_extra;
paramBuf[i].fields = fieldBuf[i];
if ((size = ValveParamToBinParam(params[i].vtype,
params[i].type,
params[i].flags,

View File

@ -159,7 +159,11 @@ static cell_t PrepSDKCall_SetSignature(IPluginContext *pContext, const cell_t *p
static cell_t PrepSDKCall_SetAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef PLATFORM_X86
s_call_addr = reinterpret_cast<void *>(params[1]);
#else
s_call_addr = g_pSM->FromPseudoAddress(params[1]);
#endif
return (s_call_addr != NULL) ? 1 : 0;
}

View File

@ -74,6 +74,8 @@ size_t ValveParamToBinParam(ValveType type,
info->type = PassType_Object;
info->flags = flags | PASSFLAG_OASSIGNOP | PASSFLAG_OCTOR;
info->size = sizeof(Vector);
info->fields[0] = info->fields[1] = info->fields[2] = ObjectField::Float;
info->numFields = 3;
} else {
return 0;
}
@ -97,6 +99,8 @@ size_t ValveParamToBinParam(ValveType type,
info->type = PassType_Object;
info->flags = flags | PASSFLAG_OASSIGNOP | PASSFLAG_OCTOR;
info->size = sizeof(QAngle);
info->fields[0] = info->fields[1] = info->fields[2] = ObjectField::Float;
info->numFields = 3;
} else {
return 0;
}

View File

@ -199,12 +199,18 @@ bool UTIL_VerifySignature(const void *addr, const char *sig, size_t len)
return true;
}
#ifdef PLATFORM_X64
#define KEY_SUFFIX "64"
#else
#define KEY_SUFFIX ""
#endif
#if defined PLATFORM_WINDOWS
#define FAKECLIENT_KEY "CreateFakeClient_Windows"
#define FAKECLIENT_KEY "CreateFakeClient_Windows" KEY_SUFFIX
#elif defined PLATFORM_LINUX
#define FAKECLIENT_KEY "CreateFakeClient_Linux"
#define FAKECLIENT_KEY "CreateFakeClient_Linux" KEY_SUFFIX
#elif defined PLATFORM_APPLE
#define FAKECLIENT_KEY "CreateFakeClient_Mac"
#define FAKECLIENT_KEY "CreateFakeClient_Mac" KEY_SUFFIX
#else
#error "Unsupported platform"
#endif
@ -273,7 +279,12 @@ void GetIServer()
}
/* Finally we have the interface we were looking for */
#ifdef PLATFORM_X86
iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
#elif defined PLATFORM_X64
int32_t varOffset = *reinterpret_cast<int32_t *>(reinterpret_cast<unsigned char *>(vfunc) + offset);
iserver = reinterpret_cast<IServer *>(reinterpret_cast<unsigned char *>(vfunc) + offset + sizeof(int32_t) + varOffset);
#endif
}
void GetResourceEntity()

View File

@ -1349,8 +1349,8 @@ static cell_t SetClientName(IPluginContext *pContext, const cell_t *params)
}
}
// The IClient vtable is +4 from the CBaseClient vtable due to multiple inheritance.
void *pGameClient = (void *)((intptr_t)pClient - 4);
// The IClient vtable is +sizeof(void *) from the CBaseClient vtable due to multiple inheritance.
void *pGameClient = (void *)((intptr_t)pClient - sizeof(void *));
// Change the name in the engine.
START_CALL();
@ -1427,7 +1427,7 @@ static cell_t SetClientInfo(IPluginContext *pContext, const cell_t *params)
}
#endif
unsigned char *CGameClient = (unsigned char *)pClient - 4;
unsigned char *CGameClient = (unsigned char *)pClient - sizeof(void *);
START_CALL();
/* Not really a CBaseEntity* but this works */

View File

@ -1,33 +1,34 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'dbi.sqlite.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'dbi.sqlite.ext', arch)
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.compiler.defines += [
'SQLITE_OMIT_LOAD_EXTENSION',
'SQLITE_THREADSAFE',
'SQLITE_USE_URI',
'SQLITE_ALLOW_URI_AUTHORITY',
]
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-ldl', '-lpthread']
binary.compiler.defines += [
'SQLITE_OMIT_LOAD_EXTENSION',
'SQLITE_THREADSAFE',
'SQLITE_USE_URI',
'SQLITE_ALLOW_URI_AUTHORITY',
]
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-ldl', '-lpthread']
binary.sources += [
'../../public/smsdk_ext.cpp',
'extension.cpp',
'driver/SqDatabase.cpp',
'driver/SqDriver.cpp',
'driver/SqQuery.cpp',
'driver/SqResults.cpp',
'sqlite-source/sqlite3.c'
]
binary.sources += [
'../../public/smsdk_ext.cpp',
'extension.cpp',
'driver/SqDatabase.cpp',
'driver/SqDriver.cpp',
'driver/SqQuery.cpp',
'driver/SqResults.cpp',
'sqlite-source/sqlite3.c'
]
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]

View File

@ -4,19 +4,27 @@ import os
if 'tf2' in SM.sdks:
sdk = SM.sdks['tf2']
binary = SM.HL2Library(builder, 'game.tf2.ext.' + sdk.ext, sdk)
binary.sources += [
'extension.cpp',
'natives.cpp',
'RegNatives.cpp',
'util.cpp',
'criticals.cpp',
'holiday.cpp',
'teleporter.cpp',
'gameplayrules.cpp',
'conditions.cpp',
'../../public/smsdk_ext.cpp',
'../../public/CDetour/detours.cpp',
'../../public/asm/asm.c'
]
SM.extensions += [builder.Add(binary)]
for arch in SM.archs:
binary = SM.HL2Library(builder, 'game.tf2.ext.' + sdk.ext, sdk, arch)
binary.sources += [
'extension.cpp',
'natives.cpp',
'RegNatives.cpp',
'util.cpp',
'criticals.cpp',
'holiday.cpp',
'teleporter.cpp',
'gameplayrules.cpp',
'conditions.cpp',
'../../public/smsdk_ext.cpp',
'../../public/CDetour/detours.cpp',
'../../public/asm/asm.c',
'../../public/libudis86/decode.c',
'../../public/libudis86/itab.c',
'../../public/libudis86/syn-att.c',
'../../public/libudis86/syn-intel.c',
'../../public/libudis86/syn.c',
'../../public/libudis86/udis86.c',
]
binary.compiler.defines += ['HAVE_STRING_H'];
SM.extensions += [builder.Add(binary)]

View File

@ -1,21 +1,22 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'topmenus.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'topmenus.ext', arch)
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
'smn_topmenus.cpp',
'TopMenu.cpp',
'TopMenuManager.cpp',
'../../public/smsdk_ext.cpp',
]
binary.sources += [
'extension.cpp',
'smn_topmenus.cpp',
'TopMenu.cpp',
'TopMenuManager.cpp',
'../../public/smsdk_ext.cpp',
]
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]

View File

@ -1,22 +1,23 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'updater.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'updater.ext', arch)
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
'MemoryDownloader.cpp',
'Updater.cpp',
'md5.cpp',
'../../public/smsdk_ext.cpp'
]
binary.sources += [
'extension.cpp',
'MemoryDownloader.cpp',
'Updater.cpp',
'md5.cpp',
'../../public/smsdk_ext.cpp'
]
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]

View File

@ -108,7 +108,9 @@
{
"windows" "11"
"linux" "12"
"linux64" "12"
"mac" "12"
"mac64" "12"
}
}
}

View File

@ -31,12 +31,16 @@
"EntInfo"
{
"linux" "4"
"linux64" "8"
"mac64" "8"
}
/* Offset into LevelShutdown */
"gEntList"
{
"linux" "13"
"linux64" "13"
"mac64" "13"
}
}
@ -53,6 +57,8 @@
{
"library" "server"
"linux" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xC7\x2A\x2A\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
"linux64" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x48\x8B\x3D\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
"mac64" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x48\x8D\x3D\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
}
}
}

View File

@ -8,145 +8,169 @@
{
"windows" "105"
"linux" "106"
"mac" "106"
"linux64" "106"
"mac64" "106"
}
"EndTouch"
{
"windows" "103"
"linux" "104"
"mac" "104"
"linux64" "104"
"mac64" "104"
}
"FireBullets"
{
"windows" "117"
"linux" "118"
"mac" "118"
"linux64" "118"
"mac64" "118"
}
"GetMaxHealth"
{
"windows" "121"
"linux" "122"
"mac" "122"
"linux64" "122"
"mac64" "122"
}
"GroundEntChanged"
{
"windows" "175"
"linux" "177"
"mac" "177"
"linux64" "177"
"mac64" "177"
}
"OnTakeDamage"
{
"windows" "67"
"linux" "68"
"mac" "68"
"linux64" "68"
"mac64" "68"
}
"OnTakeDamage_Alive"
{
"windows" "295"
"linux" "296"
"mac" "296"
"linux64" "296"
"mac64" "296"
}
"PreThink"
{
"windows" "368"
"linux" "369"
"mac" "369"
"linux64" "369"
"mac64" "369"
}
"PostThink"
{
"windows" "369"
"linux" "370"
"mac" "370"
"linux64" "370"
"mac64" "370"
}
"Reload"
{
"windows" "306"
"linux" "312"
"mac" "312"
"linux64" "312"
"mac64" "312"
}
"SetTransmit"
{
"windows" "22"
"linux" "23"
"mac" "23"
"linux64" "23"
"mac64" "23"
}
"ShouldCollide"
{
"windows" "17"
"linux" "18"
"mac" "18"
"linux64" "18"
"mac64" "18"
}
"Spawn"
{
"windows" "24"
"linux" "25"
"mac" "25"
"linux64" "25"
"mac64" "25"
}
"StartTouch"
{
"windows" "101"
"linux" "102"
"mac" "102"
"linux64" "102"
"mac64" "102"
}
"Think"
{
"windows" "51"
"linux" "52"
"mac" "52"
"linux64" "52"
"mac64" "52"
}
"Touch"
{
"windows" "102"
"linux" "103"
"mac" "103"
"linux64" "103"
"mac64" "103"
}
"TraceAttack"
{
"windows" "65"
"linux" "66"
"mac" "66"
"linux64" "66"
"mac64" "66"
}
"Use"
{
"windows" "100"
"linux" "101"
"mac" "101"
"linux64" "101"
"mac64" "101"
}
"VPhysicsUpdate"
{
"windows" "154"
"linux" "155"
"mac" "155"
"linux64" "155"
"mac64" "155"
}
"Weapon_CanSwitchTo"
{
"windows" "287"
"linux" "288"
"mac" "288"
"linux64" "288"
"mac64" "288"
}
"Weapon_CanUse"
{
"windows" "281"
"linux" "282"
"mac" "282"
"linux64" "282"
"mac64" "282"
}
"Weapon_Drop"
{
"windows" "284"
"linux" "285"
"mac" "285"
"linux64" "285"
"mac64" "285"
}
"Weapon_Equip"
{
"windows" "282"
"linux" "283"
"mac" "283"
"linux64" "283"
"mac64" "283"
}
"Weapon_Switch"
{
"windows" "285"
"linux" "286"
"mac" "286"
"linux64" "286"
"mac64" "286"
}
}
}
@ -158,7 +182,8 @@
"EntityListeners"
{
"linux" "196644"
"mac" "196644"
"linux64" "393272"
"mac64" "393272"
}
}

View File

@ -33,21 +33,29 @@
{
"windows" "4"
"linux" "20"
"linux64" "18"
"mac64" "21"
}
"GetTEName"
{
"windows" "4"
"linux" "4"
"linux64" "8"
"mac64" "8"
}
"GetTENext"
{
"windows" "8"
"linux" "8"
"linux64" "16"
"mac64" "16"
}
"TE_GetServerClass"
{
"windows" "0"
"linux" "0"
"linux64" "0"
"mac64" "0"
}
}
@ -58,6 +66,8 @@
"library" "server"
"windows" "\x89\x41\x04\xA1\x2A\x2A\x2A\x2A\x89\x41\x08\x89\x0D\x2A\x2A\x2A\x2A\xC7"
"linux" "\x55\x89\xE5\x8B\x45\x08\x8B\x55\x0C\xC7\x00\x2A\x2A\x2A\x2A\x89\x50\x04\x8B\x15\x2A\x2A\x2A\x2A"
"linux64" "\x48\x8D\x05\x2A\x2A\x2A\x2A\x55\x48\x89\x07\x48\x89\xE5\x5D\x48\x8B\x05\x2A\x2A\x2A\x2A"
"mac64" "\x55\x48\x89\xE5\x48\x8D\x05\x2A\x2A\x2A\x2A\x48\x89\x07\x48\x89\x77\x08\x48\x8B\x05\x2A\x2A\x2A\x2A"
}
}
}
@ -73,6 +83,8 @@
"library" "server"
// Fallback to IServerTools method instead on Windows, lest we add custom logic since it's no longer a thiscall on Windows in CS:GO
"linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x1C\x8B\x45\x0C\x8B\x5D\x08\x8B\x7D\x10\x85\xC0\x0F\x84\x2A\x2A\x2A\x2A\x8B\x10\x89\x04\x24\xFF\x52\x0C\x8B\x10\xB8\xFF\x1F\x00\x00\x0F\xB7\xCA\x83\xFA\xFF\x0F\x45\xC1\x8D\x04\x40\x8B\x5C\xC3\x10\xEB\x2A\x90\x2A\x2A\x2A\x2A\x89"
"linux64" "\x55\x48\x89\xE5\x41\x55\x49\x89\xD5\x41\x54\x53\x48\x89\xFB\x48\x83\xEC\x08\x48\x85\xF6\x0F\x84\xBC\x00\x00\x00"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x54\x53\x49\x89\xD7\x48\x89\xFB\x48\x85\xF6\x74\x29\x48\x8B\x06\x48\x89\xF7\xFF\x50\x18\x8B\x00\x83\xF8\xFF\x0F\xB7\xC0\xB9\xFF\x1F\x00\x00\x48\x0F\x45\xC8\x48\x8D\x04\x49\x48\xC1\xE0\x04\x48\x8D\x5C\x03\x20\xEB\x07\x48\x81\xC3\x08\x00\x06\x00\x48\x8B\x1B\x45\x31\xE4\x48\x85\xDB\x74\x58\x4C\x8D\x35\x2A\x2A\x2A\x2A\x0F"
}
}
}
@ -102,6 +114,8 @@
*/
"CreateFakeClient_Windows" "\x55\x8B\xEC\x56\xFF\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x8B"
"CreateFakeClient_Linux" "\x55\x89\xE5\x53\x83\xEC\x14\x8B\x45\x0C\xC7\x04\x24\x2A\x2A\x2A\x2A"
"CreateFakeClient_Linux64" "\x55\x48\x89\xE5\x53\x48\x83\xEC\x08\x48\x8B\x3D\x2A\x2A\x2A\x2A\xE8"
"CreateFakeClient_Mac64" "\x55\x48\x89\xE5\x53\x50\x48\x8D\x3D\x2A\x2A\x2A\x2A\x48\x8B\x07\xFF\x90\x78"
}
"Offsets"
@ -111,6 +125,8 @@
{
"windows" "8"
"linux" "13"
"linux64" "12"
"mac64" "9"
}
}
@ -132,6 +148,8 @@
{
"library" "server"
"linux" "\x55\x89\xE5\x53\x83\xEC\x14\x8B\x5D\x08\xE8\x2A\x2A\x2A\x2A\x8B\x10\x89\x04\x24"
"linux64" "\x55\x48\x89\xE5\x53\x48\x89\xFB\x48\x83\xEC\x08\xE8\x2A\x2A\x2A\x2A\x48\x89\xDE\x48\x8B\x10\x48\x89\xC7\xFF\x52\x08"
"mac64" "\xE8\x2A\x2A\x2A\x2A\x48\x8B\x08\x48\x89\xC7\x4C\x89\xFE\xFF\x51\x08"
}
}
@ -144,6 +162,8 @@
"EntityFactoryCallOffset"
{
"linux" "11"
"linux64" "13"
"mac64" "1"
}
}
}
@ -158,6 +178,8 @@
"library" "server"
"windows" "\x55\x8B\xEC\x83\x2A\x2A\x81\xEC\x2A\x2A\x2A\x2A\x8B\xC1\x53\x56\x57\x8B\x2A\x2A\x89\x2A\x2A\x2A\x33"
"linux" "\x55\x89\xE5\x57\x56\x53\x81\xEC\x7C\x01\x00\x00\x8B\x55\x08\x8B\x75\x14"
"linux64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x49\x89\xF6\x41\x55\x41\x54\x49\x89\xCC\x53"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x55\x41\x54\x53\x48\x81\xEC\x88\x01\x00\x00\xF3\x0F\x11\x85\x8C\xFE\xFF\xFF"
}
}
}
@ -178,7 +200,8 @@
/* Not 100% sure on this, why would windows change and not linux - TEST ME */
"windows" "31"
"linux" "69"
"mac" "69"
"linux64" "69"
"mac64" "69"
}
/**
* CBaseClient::SetName(char const*);
@ -189,7 +212,8 @@
{
"windows" "30"
"linux" "68"
"mac" "68"
"linux64" "68"
"mac64" "68"
}
/**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
@ -203,7 +227,8 @@
{
"windows" "484"
"linux" "464"
"mac" "464"
"linux64" "592"
"mac64" "608"
}
}
}
@ -221,91 +246,106 @@
{
"windows" "450"
"linux" "451"
"mac" "451"
"linux64" "451"
"mac64" "451"
}
"RemovePlayerItem"
{
"windows" "293"
"linux" "294"
"mac" "294"
"linux64" "294"
"mac64" "294"
}
"Weapon_GetSlot"
{
"windows" "289"
"linux" "290"
"mac" "290"
"linux64" "290"
"mac64" "290"
}
"Ignite"
{
"windows" "223"
"linux" "224"
"mac" "224"
"linux64" "224"
"mac64" "224"
}
"Extinguish"
{
"windows" "226"
"linux" "227"
"mac" "227"
"linux64" "227"
"mac64" "227"
}
"Teleport"
{
"windows" "113"
"linux" "114"
"mac" "114"
"linux64" "114"
"mac64" "114"
}
"CommitSuicide"
{
"windows" "500"
"linux" "500"
"mac" "500"
"linux64" "500"
"mac64" "500"
}
"GetVelocity"
{
"windows" "138"
"linux" "139"
"mac" "139"
"linux64" "139"
"mac64" "139"
}
"EyeAngles"
{
"windows" "129"
"linux" "130"
"mac" "130"
"linux64" "130"
"mac64" "130"
}
"AcceptInput"
{
"windows" "40"
"linux" "41"
"mac" "41"
"linux64" "41"
"mac64" "41"
}
"SetEntityModel"
{
"windows" "26"
"linux" "27"
"mac" "27"
"linux64" "27"
"mac64" "27"
}
"WeaponEquip"
{
"windows" "282"
"linux" "283"
"mac" "283"
"linux64" "283"
"mac64" "283"
}
"Activate"
{
"windows" "37"
"linux" "38"
"mac" "38"
"linux64" "38"
"mac64" "38"
}
"PlayerRunCmd"
{
"windows" "470"
"linux" "471"
"mac" "471"
"linux64" "471"
"mac64" "471"
}
"GiveAmmo"
{
"windows" "275"
"linux" "276"
"mac" "276"
"linux64" "276"
"mac64" "276"
}
}
}

View File

@ -24,7 +24,8 @@
{
"windows" "4"
"linux" "4"
"mac" "4"
"linux64" "8"
"mac64" "8"
}
// In HandleCommand_Buy_Internal
// -*(_DWORD *)(v34 + 204)
@ -32,46 +33,54 @@
{
"windows" "204"
"linux" "204"
"mac" "204"
"linux64" "324"
"mac64" "324"
}
//Offset into CheckRestartRound
"CTTeamScoreOffset"
{
"windows" "98"
"linux" "115"
"mac" "150"
"linux64" "117"
"mac64" "148"
}
//Offset into CheckRestartRound
"TTeamScoreOffset"
{
"windows" "125"
"linux" "148"
"mac" "185"
"linux64" "148"
"mac64" "177"
}
"ClanTagOffset"
{
"windows" "12"
"linux" "29"
"mac" "22"
"linux64" "13"
"mac64" "12"
}
//Offset into HandleCommand_Buy_Internal
"CCSPlayerInventoryOffset"
{
"windows" "60"
"linux" "97"
"mac" "109"
"linux64" "108"
"mac64" "73"
}
"GetItemInLoadout"
{
"windows" "8"
"linux" "9"
"mac" "9"
"linux64" "9"
"mac64" "9"
}
"GetItemDefintionByName" //_ZN15CEconItemSchema23GetItemDefinitionByNameEPKc
{
"windows" "42"
"linux" "41"
"mac" "41"
"linux64" "41"
"mac64" "41"
}
// Search for "%s (ID %llu) at backpack slot %d" (CCSPlayerInventory::DumpInventoryToConsole(bool))
// Jump to the vtable 2 functions above calls CCStrike15ItemDefinition::GetLoadoutSlot(CCStrike15ItemDefinition *this, int)
@ -80,7 +89,8 @@
{
"windows" "588"
"linux" "588"
"mac" "588"
"linux64" "908"
"mac64" "908"
}
// Offset into CEconItemSchema * to a hashmap of all itemdefs
// Offset can be found in... GetItemDefinitionMutable (easy to get offset on windows should be the same)
@ -88,7 +98,8 @@
{
"windows" "172"
"linux" "172"
"mac" "172"
"linux64" "232"
"mac64" "232"
}
}
"Signatures"
@ -98,42 +109,56 @@
"library" "server"
"windows" "\xA1\x2A\x2A\x2A\x2A\x85\xC0\x75\x2A\xA1\x2A\x2A\x2A\x2A\x56\x68\x2A\x2A\x00\x00\x8B"
"linux" "\x55\x89\xE5\x83\xEC\x08\xE8\x2A\x2A\x2A\x2A\xC9\x83\xC0\x04\xC3"
"linux64" "\x55\x48\x89\xE5\xE8\x2A\x2A\x2A\x2A\x5D\x48\x83\xC0\x08\xC3"
"mac64" "\x55\x48\x89\xE5\x41\x56\x53\x48\x8B\x1D\x2A\x2A\x2A\x2A\x48\x85\xDB\x75"
}
"RoundRespawn"
{
"library" "server"
"windows" "\x55\x8B\xEC\x83\xEC\x0C\x53\x56\x8B\xF1\x8B\x0D\x2A\x2A\x2A\x2A\x57\x8B\x01"
"linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x4C\xA1\x2A\x2A\x2A\x2A\x8B\x5D\x08\x89\x04\x24"
"linux64" "\x55\x48\x89\xE5\x41\x56\x41\x55\x41\x54\x53\x48\x89\xFB\x48\x83\xEC\x10\x4C\x8B\x25"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x54\x53\x48\x83\xEC\x10\x49\x89\xFC\x4C\x8D\x3D"
}
"SwitchTeam"
{
"library" "server"
"windows" "\x55\x8B\xEC\x83\xEC\x10\x53\x56\x8B\x75\x08\x57\x8B\xF9\x85\xF6\x0F\x88\x2A\x2A\x2A\x2A\x3B\x35"
"linux" "\x55\x89\xE5\x83\xEC\x68\x89\x75\xF8\x8B\x75\x0C\x89\x5D\xF4\x8B\x5D\x08\x89\x7D\xFC\x89\x34\x24\xE8\x2A\x2A\x2A\x2A\x85\xC0"
"linux" "55\x89\xE5\x83\xEC\x68\x89\x75\xF8\x8B\x75\x0C\x89\x5D\xF4\x8B\x5D\x08\x89\x7D\xFC\x89\x34\x24\xE8\x2A\x2A\x2A\x2A\x85\xC0"
"linux64" "\x55\x48\x89\xE5\x48\x89\x5D\xD8\x48\x89\xFB\x89\xF7\x4C\x89\x65\xE0\x41\x89\xF4"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x55\x41\x54\x53\x48\x83\xEC\x18\x89\xF3\x49\x89\xFC"
}
"HandleCommand_Buy_Internal"//Wildcard first 6 bytes for getting address for weapon price.
{
"library" "server"
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xEC\x0C\x53\x56\x57\x6A\x01"
"linux" "\x2A\x2A\x2A\x2A\x2A\x2A\x0F\xB6\x55\x14\x89\x75\xF8\x8B\x75\x08"
"linux64" "\x2A\x2A\x2A\x2A\x2A\x2A\x5D\xD8\xBB\x03\x00\x00\x00"
"mac64" "\x2A\x2A\x2A\x2A\x2A\x2A\x41\x56\x41\x55\x41\x54\x53\x48\x83\xEC\x58\x41\x89\xCF\x49\x89\xD4"
}
"CSWeaponDrop"//Wildcard first 6 bytes for CS:S DM (kept for backcompat with old SM versions)
{
"library" "server"
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x81\xEC\x2A\x2A\x2A\x2A\x53\x8B\x5D\x08\x56\x57\x6A\x00\x68"
"linux" "\x2A\x2A\x2A\x2A\x2A\x2A\x56\x53\x81\xEC\x7C\x02\x00\x00\x8B\x5D\x0C\x8B\x75\x08\x85\xDB\x74\x2A\xC7\x44\x24\x2A\x2A\x2A\x2A\x00"
"linux64" "\x2A\x2A\x2A\x2A\x2A\x2A\x41\x56\x41\x55\x45\x31\xED\x41\x54\x49\x89\xFC\x53\x48\x89\xF3\x48\x81\xEC\xE8"
"mac64" "\x2A\x2A\x2A\x2A\x2A\x2A\x41\x56\x41\x55\x41\x54\x53\x48\x81\xEC\x78\x03\x00\x00\x49\x89\xF4"
}
"CSWeaponDropBB" //Revert back to using CSWeaponDrop(weapon, bool, bool)
{
"library" "server"
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xE4\xF8\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x83\xEC\x34\x56"
"linux" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xEC\x7C\x8B\x5D\x08\x0F\xB6\x7D\x14"
"linux64" "\x55\x48\x89\xE5\x48\x89\x5D\xE0\x48\x89\xFB\x4C\x89\x65\xE8\x49\x89\xF4\x4C\x89\x6D\xF0\x41\x89\xD5\x4C\x89\x75\xF8\x48\x83\xEC\x70"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x54\x53\x48\x83\xEC\x30\x41\x89\xCC\x41\x89\xD7"
}
"TerminateRound"
{
"library" "server"
"windows" "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x2A\x53\x8B\xD9\xF3\x0F\x2A\x2A\x2A\x2A\x56\x57\x89\x2A\x2A\x2A\x83\xBB"
"linux" "\x55\x89\xE5\x57\x56\x53\x81\xEC\xBC\x00\x00\x00\x8B\x7D\x08\x8B\x9F"
"linux64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x49\x89\xFE\x41\x55\x41\x54\x53\x48\x81\xEC\xE8"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x55\x41\x54\x53\x48\x81\xEC\x08\x01\x00\x00\x41\x89\xF6"
}
//In CS:GO this is actually CCSGameRules::CheckRestartRound(void) but to keep same gamedata as cs:s.
"CheckWinLimit"
@ -141,18 +166,24 @@
"library" "server"
"windows" "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x2A\x53\x56\x57\x8B\xF9\x8B\x0D\x2A\x2A\x2A\x2A\x81\xF9"
"linux" "\x55\x89\xE5\x56\x53\x83\xEC\x70\xA1\x2A\x2A\x2A\x2A\x8B\x35\x2A\x2A\x2A\x2A\x8B"
"linux64" "\x55\x48\x89\xE5\x41\x56\x41\x55\x41\x54\x53\x48\x89\xFB\x48\x83\xEC\x50\x4C\x8B\x25\x2A\x2A\x2A\x2A\x49"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x55\x41\x54\x53\x48\x83\xEC\x58\x49\x89\xFD\x48\x8B\x1D"
}
"SetClanTag"
{
"library" "server"
"windows" "\x55\x8B\xEC\x8B\x55\x08\x85\xD2\x74\x2A\x8D\x81\x34\x25\x00\x00"
"linux" "\x55\x89\xE5\x83\xEC\x18\x8B\x45\x0C\x85\xC0\x74\x2A\x89\x44\x24\x04\x8B\x45\x08\xC7\x44\x24\x08\x10\x00\x00\x00"
"linux64" "\x55\x48\x85\xF6\x48\x89\xE5\x74\x17\x5D\x48\x81\xC7\x2A\x2A\x2A\x2A\xBA\x10"
"mac64" "\x55\x48\x89\xE5\x48\x85\xF6\x74\x12\x48\x81\xC7\x2A\x2A\x2A\x2A\xBA\x10"
}
"SetModelFromClass"
{
"library" "server"
"windows" "\x53\x56\x57\x8B\xF9\x8B\x87\x00\x03\x00\x00"
"linux" "\x55\x89\xE5\x83\xEC\x28\x89\x5D\xF4\x8B\x5D\x08\x89\x75\xF8\x89\x7D\xFC\x89\x1C\x24\xE8\x2A\x2A\x2A\x2A\x83\xF8\x02"
"linux64" "\x55\x48\x89\xE5\x48\x89\x5D\xE0\x48\x89\xFB\x4C\x89\x65\xE8\x4C\x89\x6D\xF0\x4C\x89\x75\xF8\x48\x83\xEC\x20\xE8\x2A\x2A\x2A\x2A\x83\xF8\x02"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x54\x53\x49\x89\xFC\xE8\x2A\x2A\x2A\x2A\x83\xF8\x02"
}
//GetCCSWeaponData Found in HandleCommand_Buy_Internal
//Uses an econitemview
@ -161,6 +192,8 @@
"library" "server"
"windows" "\x85\xC9\x75\x2A\x33\xC0\xC3\xE8\x2A\x2A\x2A\x2A\x8B"
"linux" "\x55\x89\xE5\x83\xEC\x18\x8B\x45\x08\x85\xC0\x74\x2A\x89\x04\x24"
"linux64" "\x55\x48\x85\xFF\x48\x89\xE5\x74\x17\xE8\x2A\x2A\x2A\x2A\x5D"
"mac64" "\x55\x48\x89\xE5\x41\x56\x53\x31\xC0\x48\x85\xFF\x74\x2E"
}
}
}
@ -178,7 +211,8 @@
{
"windows" "4"
"linux" "4"
"mac" "4"
"linux64" "4"
"mac64" "4"
}
}
}
@ -196,7 +230,8 @@
{
"windows" "75"
"linux" "75"
"mac" "75"
"linux64" "75"
"mac64" "75"
}
}
}
@ -214,7 +249,8 @@
{
"windows" "15"
"linux" "15"
"mac" "15"
"linux64" "15"
"mac64" "15"
}
}
}

View File

@ -1,27 +1,31 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os.path
if builder.target.platform in ['windows', 'mac']:
name = 'sourcemod_mm'
extra_ldflags = []
elif builder.target.platform == 'linux':
name = 'sourcemod_mm_i486'
extra_ldflags = ['-ldl']
for arch in SM.archs:
if builder.target.platform in ['windows', 'mac']:
name = 'sourcemod_mm'
extra_ldflags = []
elif builder.target.platform == 'linux':
name = 'sourcemod_mm_i486'
extra_ldflags = ['-ldl']
binary = SM.Library(builder, name)
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core'),
os.path.join(SM.mms_root, 'sourcehook')
]
binary.compiler.defines += ['META_NO_HL2SDK']
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.compiler.linkflags += extra_ldflags
binary.sources = [
'loader.cpp'
]
if arch == 'x64':
name = 'sourcemod_mm.x64'
nodes = builder.Add(binary)
SM.binaries += [nodes]
binary = SM.Library(builder, name, arch)
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core'),
os.path.join(SM.mms_root, 'sourcehook')
]
binary.compiler.defines += ['META_NO_HL2SDK']
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.compiler.linkflags += extra_ldflags
binary.sources = [
'loader.cpp'
]
nodes = builder.Add(binary)
SM.binaries += [nodes]

View File

@ -57,28 +57,34 @@
#include <dlfcn.h>
#endif
#if defined(_WIN64) || defined(__x86_64__)
#define PLATFORM_ARCH_FOLDER "x64" PATH_SEP_CHAR
#else
#define PLATFORM_ARCH_FOLDER ""
#endif
#define METAMOD_API_MAJOR 2
#define FILENAME_1_6_EP2 "sourcemod.2.ep2" PLATFORM_EXT
#define FILENAME_1_6_EP1 "sourcemod.2.ep1" PLATFORM_EXT
#define FILENAME_1_6_L4D "sourcemod.2.l4d" PLATFORM_EXT
#define FILENAME_1_6_DARKM "sourcemod.2.darkm" PLATFORM_EXT
#define FILENAME_1_6_L4D2 "sourcemod.2.l4d2" PLATFORM_EXT
#define FILENAME_1_6_SWARM "sourcemod.2.swarm" PLATFORM_EXT
#define FILENAME_1_6_BGT "sourcemod.2.bgt" PLATFORM_EXT
#define FILENAME_1_6_EYE "sourcemod.2.eye" PLATFORM_EXT
#define FILENAME_1_6_PORTAL2 "sourcemod.2.portal2" PLATFORM_EXT
#define FILENAME_1_6_CSGO "sourcemod.2.csgo" PLATFORM_EXT
#define FILENAME_1_6_CSS "sourcemod.2.css" PLATFORM_EXT
#define FILENAME_1_6_HL2DM "sourcemod.2.hl2dm" PLATFORM_EXT
#define FILENAME_1_6_DODS "sourcemod.2.dods" PLATFORM_EXT
#define FILENAME_1_6_SDK2013 "sourcemod.2.sdk2013" PLATFORM_EXT
#define FILENAME_1_6_TF2 "sourcemod.2.tf2" PLATFORM_EXT
#define FILENAME_1_6_ND "sourcemod.2.nd" PLATFORM_EXT
#define FILENAME_1_6_BLADE "sourcemod.2.blade" PLATFORM_EXT
#define FILENAME_1_6_INSURGENCY "sourcemod.2.insurgency" PLATFORM_EXT
#define FILENAME_1_6_DOI "sourcemod.2.doi" PLATFORM_EXT
#define FILENAME_1_6_CONTAGION "sourcemod.2.contagion" PLATFORM_EXT
#define FILENAME_1_6_BMS "sourcemod.2.bms" PLATFORM_EXT
#define FILENAME_1_6_EP2 PLATFORM_ARCH_FOLDER "sourcemod.2.ep2" PLATFORM_EXT
#define FILENAME_1_6_EP1 PLATFORM_ARCH_FOLDER "sourcemod.2.ep1" PLATFORM_EXT
#define FILENAME_1_6_L4D PLATFORM_ARCH_FOLDER "sourcemod.2.l4d" PLATFORM_EXT
#define FILENAME_1_6_DARKM PLATFORM_ARCH_FOLDER "sourcemod.2.darkm" PLATFORM_EXT
#define FILENAME_1_6_L4D2 PLATFORM_ARCH_FOLDER "sourcemod.2.l4d2" PLATFORM_EXT
#define FILENAME_1_6_SWARM PLATFORM_ARCH_FOLDER "sourcemod.2.swarm" PLATFORM_EXT
#define FILENAME_1_6_BGT PLATFORM_ARCH_FOLDER "sourcemod.2.bgt" PLATFORM_EXT
#define FILENAME_1_6_EYE PLATFORM_ARCH_FOLDER "sourcemod.2.eye" PLATFORM_EXT
#define FILENAME_1_6_PORTAL2 PLATFORM_ARCH_FOLDER "sourcemod.2.portal2" PLATFORM_EXT
#define FILENAME_1_6_CSGO PLATFORM_ARCH_FOLDER "sourcemod.2.csgo" PLATFORM_EXT
#define FILENAME_1_6_CSS PLATFORM_ARCH_FOLDER "sourcemod.2.css" PLATFORM_EXT
#define FILENAME_1_6_HL2DM PLATFORM_ARCH_FOLDER "sourcemod.2.hl2dm" PLATFORM_EXT
#define FILENAME_1_6_DODS PLATFORM_ARCH_FOLDER "sourcemod.2.dods" PLATFORM_EXT
#define FILENAME_1_6_SDK2013 PLATFORM_ARCH_FOLDER "sourcemod.2.sdk2013" PLATFORM_EXT
#define FILENAME_1_6_TF2 PLATFORM_ARCH_FOLDER "sourcemod.2.tf2" PLATFORM_EXT
#define FILENAME_1_6_ND PLATFORM_ARCH_FOLDER "sourcemod.2.nd" PLATFORM_EXT
#define FILENAME_1_6_BLADE PLATFORM_ARCH_FOLDER "sourcemod.2.blade" PLATFORM_EXT
#define FILENAME_1_6_INSURGENCY PLATFORM_ARCH_FOLDER "sourcemod.2.insurgency" PLATFORM_EXT
#define FILENAME_1_6_DOI PLATFORM_ARCH_FOLDER "sourcemod.2.doi" PLATFORM_EXT
#define FILENAME_1_6_CONTAGION PLATFORM_ARCH_FOLDER "sourcemod.2.contagion" PLATFORM_EXT
#define FILENAME_1_6_BMS PLATFORM_ARCH_FOLDER "sourcemod.2.bms" PLATFORM_EXT
HINSTANCE g_hCore = NULL;
bool load_attempted = false;

View File

@ -41,6 +41,8 @@
#define PAGE_EXECUTE_READWRITE PROT_READ|PROT_WRITE|PROT_EXEC
#endif
#include <jit/x86/x86_macros.h>
struct patch_t
{
patch_t()
@ -68,13 +70,50 @@ 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 <lower 32-bits> ; allocates 64-bit stack space on x64
// mov [rsp+4], <upper 32-bits> ; 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)
{
SetMemPatchable(target, 20);
target[0] = 0xFF; /* JMP */
target[1] = 0x25; /* MEM32 */
*(void **)(&target[2]) = 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)

View File

@ -35,6 +35,58 @@
ISourcePawnEngine *CDetourManager::spengine = NULL;
IGameConfig *CDetourManager::gameconf = NULL;
// Push 64-bit value onto the stack using two instructions.
//
// Pushing 0xF00DF00DF00DF00D:
// push 0xF00DF00D
// mov [rsp+4], 0xF00DF00D
static inline void X64_Push_Imm64(JitWriter *jit, jit_int64_t val)
{
jit->write_ubyte(IA32_PUSH_IMM32);
jit->write_int32(jit_int32_t(val));
if ((val >> 32) != 0)
IA32_Mov_ESP_Disp8_Imm32(jit, 4, (val >> 32));
}
// Jump to absolute 64-bit address using multiple instructions.
//
// Jumping to address 0xF00DF00DF00DF00D:
// push 0xF00DF00D
// mov [rsp+4], 0xF00DF00D
// ret
static inline void X64_Jump_Abs(JitWriter *jit, void *dest)
{
X64_Push_Imm64(jit, jit_int64_t(dest));
IA32_Return(jit);
}
static inline void RelativeJump32(JitWriter *jit, void *target)
{
jitoffs_t call = IA32_Jump_Imm32(jit, 0);
IA32_Write_Jump32_Abs(jit, call, target);
}
#if defined(_WIN64) || defined(__x86_64__)
static inline bool IsShortJump(JitWriter *jit, void *target)
{
int64_t diff = int64_t(target) - (int64_t(jit->outbase) + jit->get_outputpos() + OP_JMP_SIZE);
int32_t upperBits = (diff >> 32);
return upperBits == 0 || upperBits == -1;
}
#endif
static inline void AbsJump(JitWriter *jit, void *target)
{
#if defined(_WIN64) || defined(__x86_64__)
if (IsShortJump(jit, target))
RelativeJump32(jit, target);
else
X64_Jump_Abs(jit, target);
#else
RelativeJump32(jit, target);
#endif
}
void CDetourManager::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf)
{
CDetourManager::spengine = spengine;
@ -147,13 +199,12 @@ bool CDetour::CreateDetour()
return false;
}
detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE+1);
/* First, save restore bits */
for (size_t i=0; i<detour_restore.bytes; i++)
{
detour_restore.patch[i] = ((unsigned char *)detour_address)[i];
}
#if defined(_WIN64) || defined(__x86_64__)
int shortBytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE);
detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, X64_ABS_SIZE);
#else
detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE);
#endif
JitWriter wr;
JitWriter *jit = &wr;
@ -167,13 +218,22 @@ jit_rewind:
/* Patch old bytes in */
if (wr.outbase != NULL)
{
#if defined(_WIN64) || defined(__x86_64__)
wr.outptr += shortBytes;
bool isShort = IsShortJump(jit, detour_address);
wr.outptr -= shortBytes;
if (isShort)
detour_restore.bytes = shortBytes;
#endif
/* Save restore bits */
memcpy(detour_restore.patch, detour_address, detour_restore.bytes);
copy_bytes((unsigned char *)detour_address, (unsigned char*)wr.outptr, detour_restore.bytes);
}
wr.outptr += detour_restore.bytes;
/* Return to the original function */
jitoffs_t call = IA32_Jump_Imm32(jit, 0);
IA32_Write_Jump32_Abs(jit, call, (unsigned char *)detour_address + detour_restore.bytes);
AbsJump(jit, (unsigned char *)detour_address + detour_restore.bytes);
if (wr.outbase == NULL)
{
@ -211,7 +271,7 @@ void CDetour::EnableDetour()
{
if (!detoured)
{
DoGatePatch((unsigned char *)detour_address, &detour_callback);
DoGatePatch((unsigned char *)detour_address, detour_callback);
detoured = true;
}
}

View File

@ -43,7 +43,7 @@
#include <time.h>
#define SMINTERFACE_SOURCEMOD_NAME "ISourceMod"
#define SMINTERFACE_SOURCEMOD_VERSION 13
#define SMINTERFACE_SOURCEMOD_VERSION 14
/**
* @brief Forward declaration of the KeyValues class.
@ -318,6 +318,20 @@ namespace SourceMod
* @return True if a map is currently running, otherwise false.
*/
virtual bool IsMapRunning() = 0;
/**
* @brief Converts 32-bit pseudo address to memory address on 64-bit platforms.
*
* @return Memory address, or nullptr if pseudo address could not be converted.
*/
virtual void *FromPseudoAddress(uint32_t pseudoAddr) = 0;
/**
* @brief Converts memory address to 32-bit pseudo address on 64-bit platforms.
*
* @return Pseudo address, or 0 if memory address could not be converted.
*/
virtual uint32_t ToPseudoAddress(void *addr) = 0;
};
}

View File

@ -1,11 +1,13 @@
#include "asm.h"
#include "libudis86/udis86.h"
#ifndef WIN32
#define _GNU_SOURCE
#include <dlfcn.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "libudis86/udis86.h"
#define REG_EAX 0
#define REG_ECX 1
@ -25,7 +27,9 @@
*/
void check_thunks(unsigned char *dest, unsigned char *pc)
{
#ifndef WIN32
#if defined(_WIN32) || defined(__x86_64__)
return;
#else
/* Step write address back 4 to the start of the function address */
unsigned char *writeaddr = dest - 4;
unsigned char *calloffset = *(unsigned char **)writeaddr;
@ -85,6 +89,59 @@ void check_thunks(unsigned char *dest, unsigned char *pc)
#endif
}
int copy_bytes(unsigned char *func, unsigned char *dest, int required_len)
{
ud_t ud_obj;
ud_init(&ud_obj);
#if defined(_WIN64) || defined(__x86_64__)
ud_set_mode(&ud_obj, 64);
#else
ud_set_mode(&ud_obj, 32);
#endif
ud_set_input_buffer(&ud_obj, func, 20);
unsigned int bytecount = 0;
while (bytecount < required_len && ud_disassemble(&ud_obj))
{
unsigned int insn_len = ud_insn_len(&ud_obj);
bytecount += insn_len;
if (dest)
{
const uint8_t *opcode = ud_insn_ptr(&ud_obj);
if ((opcode[0] & 0xFE) == 0xE8) // Fix CALL/JMP offset
{
dest[0] = func[0];
dest++; func++;
if (ud_insn_opr(&ud_obj, 0)->size == 32)
{
*(int32_t *)dest = func + *(int32_t *)func - dest;
check_thunks(dest+4, func+4);
dest += sizeof(int32_t);
}
else
{
*(int16_t *)dest = func + *(int16_t *)func - dest;
dest += sizeof(int16_t);
}
func--;
}
else
{
memcpy(dest, func, insn_len);
dest += insn_len;
}
}
func += insn_len;
}
return bytecount;
}
#if 0
//if dest is NULL, returns minimum number of bytes needed to be copied
//if dest is not NULL, it will copy the bytes to dest as well as fix CALLs and JMPs
//http://www.devmaster.net/forums/showthread.php?t=2311
@ -336,6 +393,7 @@ int copy_bytes(unsigned char *func, unsigned char* dest, int required_len) {
return bytecount;
}
#endif
//insert a specific JMP instruction at the given location
void inject_jmp(void* src, void* dest) {

View File

@ -3,6 +3,7 @@
#define OP_JMP 0xE9
#define OP_JMP_SIZE 5
#define X64_ABS_SIZE 14
#define OP_NOP 0x90
#define OP_NOP_SIZE 1

View File

@ -36,20 +36,7 @@
#define SMINTERFACE_BINTOOLS_NAME "IBinTools"
#define SMINTERFACE_BINTOOLS_VERSION 3
#if defined METAMOD_PLAPI_VERSION
#ifndef HOOKING_ENABLED
#define HOOKING_ENABLED
#endif
#endif
#if defined HOOKING_ENABLED
#include <sourcehook_pibuilder.h>
#define SMINTERFACE_BINTOOLS2_NAME "IBinTools2"
#define SMINTERFACE_BINTOOLS2_VERSION 1
#endif
#define SMINTERFACE_BINTOOLS_VERSION 4
/**
* @brief Function calling encoding utilities
@ -82,15 +69,42 @@ namespace SourceMod
#define PASSFLAG_ODTOR (1<<2) /**< Object has a destructor */
#define PASSFLAG_OCTOR (1<<3) /**< Object has a constructor */
#define PASSFLAG_OASSIGNOP (1<<4) /**< Object has an assignment operator */
#define PASSFLAG_OCOPYCTOR (1<<5) /**< Object has non-trivial copy constructor */
#define PASSFLAG_OUNALIGN (1<<6) /**< Object contains unaligned fields */
#define FNFLAG_VARARGS (1<<0) /**< Function has variable arguments */
enum class ObjectField
{
Boolean,
Int8,
Int16,
Int32,
Int64,
Pointer,
Float,
Double
};
/**
* @brief Parameter passing information
*/
struct PassInfo
{
PassInfo() : fields(nullptr), numFields(0)
{ }
PassInfo(PassType type, unsigned int flags, size_t size, ObjectField *fields, unsigned int numFields)
: type(type), flags(flags), size(size), fields(fields), numFields(numFields)
{ }
PassType type; /**< PassType value */
unsigned int flags; /**< Pass/return flags */
size_t size; /**< Size of the data being passed */
ObjectField *fields; /**< List of fields for PassType_Object.
Can be ignored if size of object is > 16 bytes */
unsigned int numFields; /**< Number of object fields.
Can be ignored if size of object is > 16 bytes */
};
/**
@ -150,108 +164,12 @@ namespace SourceMod
*/
virtual void Destroy() =0;
#if defined HOOKING_ENABLED
/**
* @brief Gets the Return type info.
*
* @return A PassInfo pointer.
* @brief Returns the function's flags.
*/
virtual const SourceHook::PassInfo *GetSHReturnInfo() =0;
/**
* @brief Returns the calling convention.
*
* @return CallConvention value.
*/
virtual SourceHook::ProtoInfo::CallConvention GetSHCallConvention() =0;
/**
* @brief Returns parameter info.
*
* @param num Parameter number to get (starting from 0).
* @return A PassInfo pointer.
*/
virtual const SourceHook::PassInfo *GetSHParamInfo(unsigned int num) =0;
/**
* @brief Returns the offset of a given param.
*
* @param num Parameter number to get (starting from 0).
* @return Parameter offset.
*/
virtual unsigned int GetParamOffset(unsigned int num) =0;
#endif
virtual unsigned int GetFunctionFlags() =0;
};
#if defined HOOKING_ENABLED
/**
* @brief Delegate object that intermediates between SourceHook and the callback function.
*/
class ISMDelegate : public SourceHook::ISHDelegate
{
private:
/**
* @brief Internally used callback function - Do not call!
*/
virtual void Call() =0; /**< Do not call */
public:
/**
* @brief Retrieves the User data buffer.
*
* @return User data pointer.
*/
virtual void *GetUserData() =0;
};
/**
* @brief Wrapper around a virtual hook.
*/
class IHookWrapper
{
public:
/**
* @brief Creates a hook delegate to pass to SourceHook.
*
* @param data User data pointer.
* @return A new ISMDelegate for the hook.
*/
virtual ISMDelegate *CreateDelegate(void *data) =0;
/**
* @brief Gets the number of params in the hooked function.
*
* @return Number of params.
*/
virtual unsigned int GetParamCount() =0;
/**
* @brief Returns the offset of a given param.
*
* @param argnum Parameter number from 0 to GetParamCount-1.
* @param size Optional buffer to store the size of the param.
* @return Parameter offset or -1 on error.
*/
virtual unsigned int GetParamOffset(unsigned int argnum, unsigned int *size) =0;
/**
* @brief Initiates a recall on the function.
*
* @param params Parameter buffer.
* @param retval Buffer to store the return value in.
*/
virtual void PerformRecall(void *params, void *retval) =0;
/**
* @brief Destroys this HookWrapper.
*/
virtual void Destroy() =0;
};
#endif
/**
* @brief Binary tools interface.
*/
@ -280,13 +198,15 @@ namespace SourceMod
* @param retInfo Return type information, or NULL for void.
* @param paramInfo Array of parameters.
* @param numParams Number of parameters in the array.
* @param fnFlags Function flags. See FNFLAG_* above.
* @return A new ICallWrapper function.
*/
virtual ICallWrapper *CreateCall(void *address,
CallConvention cv,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams) =0;
unsigned int numParams,
unsigned int fnFlags=0) =0;
/**
* @brief Creates a vtable call decoder.
@ -302,6 +222,7 @@ namespace SourceMod
* @param retInfo Return type information, or NULL for void.
* @param paramInfo Array of parameters.
* @param numParams Number of parameters in the array.
* @param fnFlags Function flags. See FNFLAG_* above.
* @return A new ICallWrapper function.
*/
virtual ICallWrapper *CreateVCall(unsigned int vtblIdx,
@ -309,84 +230,10 @@ namespace SourceMod
unsigned int thisOffs,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams) =0;
unsigned int numParams,
unsigned int fnFlags=0) =0;
};
#if defined HOOKING_ENABLED
/**
* @brief Binary tools interface.
*/
class IBinTools2 : public SMInterface
{
public:
virtual const char *GetInterfaceName()
{
return SMINTERFACE_BINTOOLS2_NAME;
}
virtual unsigned int GetInterfaceVersion()
{
return SMINTERFACE_BINTOOLS2_VERSION;
}
public:
/**
* @brief Creates a call decoder.
*
* Note: CallConv_ThisCall requires an implicit first parameter
* of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However,
* this should only be given to the Execute() function, and never
* listed in the paramInfo array.
*
* @param address Address to use as a call.
* @param protoInfo Parameter type information.
* @return A new ICallWrapper function.
*/
virtual ICallWrapper *CreateCall(void *address,
const SourceHook::ProtoInfo *protoInfo) =0;
/**
* @brief Creates a vtable call decoder.
*
* Note: CallConv_ThisCall requires an implicit first parameter
* of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However,
* this should only be given to the Execute() function, and never
* listed in the paramInfo array.
*
* @param protoInfo Parameter type information.
* @param info Function offset information.
* @return A new ICallWrapper function.
*/
virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info) =0;
/**
* @brief Callback function pointer for Virtual Hooks.
*
* @param wrapper Call wrapper for this hook.
* @param deleg Delegate for this call.
* @param params Array of parameters.
* @param ret Storage buffer for the return value.
*/
typedef void (*VIRTUAL_HOOK_PROTO)(IHookWrapper *wrapper, ISMDelegate *deleg, void *params, void *ret);
/**
* @brief Creates a hook on a virtual function.
*
* @param pSH Global SourceHook pointer.
* @param protoInfo Parameter type information.
* @param info Function offset information.
* @param f Callback function pointer.
*/
virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH,
const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info,
VIRTUAL_HOOK_PROTO f) =0;
};
#endif
}
#endif //_INCLUDE_SMEXT_BINTOOLS_H_

View File

@ -115,6 +115,22 @@ public:
}
outptr += sizeof(jit_uint32_t);
}
inline void write_int64(jit_int64_t c)
{
if (outbase)
{
*(jit_int64_t *)outptr = c;
}
outptr += sizeof(jit_int64_t);
}
inline void write_uint64(jit_uint64_t c)
{
if (outbase)
{
*(jit_uint64_t *)outptr = c;
}
outptr += sizeof(jit_uint64_t);
}
inline jitoffs_t get_outputpos()
{
return (outptr - outbase);

View File

@ -102,6 +102,7 @@ const jit_uint8_t kREG_EDI = 7;
#define IA32_MOV_RM_REG 0x89 // encoding is /r
#define IA32_MOV_REG8_RM8 0x8A // encoding is /r
#define IA32_MOV_REG_RM 0x8B // encoding is /r
#define IA32_MOV_RM_IMM32 0xC7 // encoding is /0
#define IA32_LEA_REG_MEM 0x8D // encoding is /r
#define IA32_MOVSB 0xA4 // no extra encoding
#define IA32_MOVSD 0xA5 // no extra encoding
@ -465,5 +466,14 @@ inline jitoffs_t IA32_Jump_Imm32(JitWriter *jit, jit_int32_t disp)
return ptr;
}
inline void IA32_Mov_ESP_Disp8_Imm32(JitWriter *jit, jit_int8_t disp8, jit_int32_t val)
{
jit->write_ubyte(IA32_MOV_RM_IMM32);
jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, kREG_SIB));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_ESP));
jit->write_byte(disp8);
jit->write_int32(val);
}
#endif //_INCLUDE_JIT_X86_MACROS_H

1112
public/libudis86/decode.c Normal file

File diff suppressed because it is too large Load Diff

195
public/libudis86/decode.h Normal file
View File

@ -0,0 +1,195 @@
/* udis86 - libudis86/decode.h
*
* Copyright (c) 2002-2009 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UD_DECODE_H
#define UD_DECODE_H
#include "types.h"
#include "itab.h"
#define MAX_INSN_LENGTH 15
/* itab prefix bits */
#define P_none ( 0 )
#define P_cast ( 1 << 0 )
#define P_CAST(n) ( ( n >> 0 ) & 1 )
#define P_rexb ( 1 << 1 )
#define P_REXB(n) ( ( n >> 1 ) & 1 )
#define P_inv64 ( 1 << 4 )
#define P_INV64(n) ( ( n >> 4 ) & 1 )
#define P_rexw ( 1 << 5 )
#define P_REXW(n) ( ( n >> 5 ) & 1 )
#define P_def64 ( 1 << 7 )
#define P_DEF64(n) ( ( n >> 7 ) & 1 )
#define P_rexr ( 1 << 8 )
#define P_REXR(n) ( ( n >> 8 ) & 1 )
#define P_oso ( 1 << 9 )
#define P_OSO(n) ( ( n >> 9 ) & 1 )
#define P_aso ( 1 << 10 )
#define P_ASO(n) ( ( n >> 10 ) & 1 )
#define P_rexx ( 1 << 11 )
#define P_REXX(n) ( ( n >> 11 ) & 1 )
#define P_ImpAddr ( 1 << 12 )
#define P_IMPADDR(n) ( ( n >> 12 ) & 1 )
#define P_seg ( 1 << 13 )
#define P_SEG(n) ( ( n >> 13 ) & 1 )
#define P_str ( 1 << 14 )
#define P_STR(n) ( ( n >> 14 ) & 1 )
#define P_strz ( 1 << 15 )
#define P_STR_ZF(n) ( ( n >> 15 ) & 1 )
/* operand type constants -- order is important! */
enum ud_operand_code {
OP_NONE,
OP_A, OP_E, OP_M, OP_G,
OP_I, OP_F,
OP_R0, OP_R1, OP_R2, OP_R3,
OP_R4, OP_R5, OP_R6, OP_R7,
OP_AL, OP_CL, OP_DL,
OP_AX, OP_CX, OP_DX,
OP_eAX, OP_eCX, OP_eDX,
OP_rAX, OP_rCX, OP_rDX,
OP_ES, OP_CS, OP_SS, OP_DS,
OP_FS, OP_GS,
OP_ST0, OP_ST1, OP_ST2, OP_ST3,
OP_ST4, OP_ST5, OP_ST6, OP_ST7,
OP_J, OP_S, OP_O,
OP_I1, OP_I3, OP_sI,
OP_V, OP_W, OP_Q, OP_P,
OP_U, OP_N, OP_MU,
OP_R, OP_C, OP_D,
OP_MR
} UD_ATTR_PACKED;
/* operand size constants */
enum ud_operand_size {
SZ_NA = 0,
SZ_Z = 1,
SZ_V = 2,
SZ_RDQ = 7,
/* the following values are used as is,
* and thus hard-coded. changing them
* will break internals
*/
SZ_B = 8,
SZ_W = 16,
SZ_D = 32,
SZ_Q = 64,
SZ_T = 80,
SZ_O = 128,
SZ_Y = 17,
/*
* complex size types, that encode sizes for operands
* of type MR (memory or register), for internal use
* only. Id space 256 and above.
*/
SZ_BD = (SZ_B << 8) | SZ_D,
SZ_BV = (SZ_B << 8) | SZ_V,
SZ_WD = (SZ_W << 8) | SZ_D,
SZ_WV = (SZ_W << 8) | SZ_V,
SZ_WY = (SZ_W << 8) | SZ_Y,
SZ_DY = (SZ_D << 8) | SZ_Y,
SZ_WO = (SZ_W << 8) | SZ_O,
SZ_DO = (SZ_D << 8) | SZ_O,
SZ_QO = (SZ_Q << 8) | SZ_O,
} UD_ATTR_PACKED;
/* resolve complex size type.
*/
static inline enum ud_operand_size
Mx_mem_size(enum ud_operand_size size)
{
return (size >> 8) & 0xff;
}
static inline enum ud_operand_size
Mx_reg_size(enum ud_operand_size size)
{
return size & 0xff;
}
/* A single operand of an entry in the instruction table.
* (internal use only)
*/
struct ud_itab_entry_operand
{
enum ud_operand_code type;
enum ud_operand_size size;
};
/* A single entry in an instruction table.
*(internal use only)
*/
struct ud_itab_entry
{
enum ud_mnemonic_code mnemonic;
struct ud_itab_entry_operand operand1;
struct ud_itab_entry_operand operand2;
struct ud_itab_entry_operand operand3;
uint32_t prefix;
};
struct ud_lookup_table_list_entry {
const uint16_t *table;
enum ud_table_type type;
const char *meta;
};
static inline int
ud_opcode_field_sext(uint8_t primary_opcode)
{
return (primary_opcode & 0x02) != 0;
}
extern struct ud_itab_entry ud_itab[];
extern struct ud_lookup_table_list_entry ud_lookup_table_list[];
#endif /* UD_DECODE_H */
/* vim:cindent
* vim:expandtab
* vim:ts=4
* vim:sw=4
*/

105
public/libudis86/extern.h Normal file
View File

@ -0,0 +1,105 @@
/* udis86 - libudis86/extern.h
*
* Copyright (c) 2002-2009, 2013 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UD_EXTERN_H
#define UD_EXTERN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "types.h"
/* ============================= PUBLIC API ================================= */
extern void ud_init(struct ud*);
extern void ud_set_mode(struct ud*, uint8_t);
extern void ud_set_pc(struct ud*, uint64_t);
extern void ud_set_input_hook(struct ud*, int (*)(struct ud*));
extern void ud_set_input_buffer(struct ud*, const uint8_t*, size_t);
#ifndef __UD_STANDALONE__
extern void ud_set_input_file(struct ud*, FILE*);
#endif /* __UD_STANDALONE__ */
extern void ud_set_vendor(struct ud*, unsigned);
extern void ud_set_syntax(struct ud*, void (*)(struct ud*));
extern void ud_input_skip(struct ud*, size_t);
extern int ud_input_end(const struct ud*);
extern unsigned int ud_decode(struct ud*);
extern unsigned int ud_disassemble(struct ud*);
extern void ud_translate_intel(struct ud*);
extern void ud_translate_att(struct ud*);
extern const char* ud_insn_asm(const struct ud* u);
extern const uint8_t* ud_insn_ptr(const struct ud* u);
extern uint64_t ud_insn_off(const struct ud*);
extern const char* ud_insn_hex(struct ud*);
extern unsigned int ud_insn_len(const struct ud* u);
extern const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n);
extern int ud_opr_is_sreg(const struct ud_operand *opr);
extern int ud_opr_is_gpr(const struct ud_operand *opr);
extern enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u);
extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c);
extern void ud_set_user_opaque_data(struct ud*, void*);
extern void* ud_get_user_opaque_data(const struct ud*);
extern uint64_t ud_insn_sext_imm(const struct ud*, const struct ud_operand*);
extern void ud_set_asm_buffer(struct ud *u, char *buf, size_t size);
extern void ud_set_sym_resolver(struct ud *u,
const char* (*resolver)(struct ud*,
uint64_t addr,
int64_t *offset));
/* ========================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* UD_EXTERN_H */

8401
public/libudis86/itab.c Normal file

File diff suppressed because it is too large Load Diff

678
public/libudis86/itab.h Normal file
View File

@ -0,0 +1,678 @@
#ifndef UD_ITAB_H
#define UD_ITAB_H
/* itab.h -- generated by udis86:scripts/ud_itab.py, do no edit */
/* ud_table_type -- lookup table types (see decode.c) */
enum ud_table_type {
UD_TAB__OPC_TABLE,
UD_TAB__OPC_X87,
UD_TAB__OPC_MOD,
UD_TAB__OPC_VEX_M,
UD_TAB__OPC_VEX_P,
UD_TAB__OPC_RM,
UD_TAB__OPC_VENDOR,
UD_TAB__OPC_OSIZE,
UD_TAB__OPC_MODE,
UD_TAB__OPC_3DNOW,
UD_TAB__OPC_REG,
UD_TAB__OPC_ASIZE,
UD_TAB__OPC_SSE
};
/* ud_mnemonic -- mnemonic constants */
enum ud_mnemonic_code {
UD_Iinvalid,
UD_I3dnow,
UD_Inone,
UD_Idb,
UD_Ipause,
UD_Iaaa,
UD_Iaad,
UD_Iaam,
UD_Iaas,
UD_Iadc,
UD_Iadd,
UD_Iaddpd,
UD_Iaddps,
UD_Iaddsd,
UD_Iaddss,
UD_Iand,
UD_Iandpd,
UD_Iandps,
UD_Iandnpd,
UD_Iandnps,
UD_Iarpl,
UD_Imovsxd,
UD_Ibound,
UD_Ibsf,
UD_Ibsr,
UD_Ibswap,
UD_Ibt,
UD_Ibtc,
UD_Ibtr,
UD_Ibts,
UD_Icall,
UD_Icbw,
UD_Icwde,
UD_Icdqe,
UD_Iclc,
UD_Icld,
UD_Iclflush,
UD_Iclgi,
UD_Icli,
UD_Iclts,
UD_Icmc,
UD_Icmovo,
UD_Icmovno,
UD_Icmovb,
UD_Icmovae,
UD_Icmovz,
UD_Icmovnz,
UD_Icmovbe,
UD_Icmova,
UD_Icmovs,
UD_Icmovns,
UD_Icmovp,
UD_Icmovnp,
UD_Icmovl,
UD_Icmovge,
UD_Icmovle,
UD_Icmovg,
UD_Icmp,
UD_Icmppd,
UD_Icmpps,
UD_Icmpsb,
UD_Icmpsw,
UD_Icmpsd,
UD_Icmpsq,
UD_Icmpss,
UD_Icmpxchg,
UD_Icmpxchg8b,
UD_Icmpxchg16b,
UD_Icomisd,
UD_Icomiss,
UD_Icpuid,
UD_Icvtdq2pd,
UD_Icvtdq2ps,
UD_Icvtpd2dq,
UD_Icvtpd2pi,
UD_Icvtpd2ps,
UD_Icvtpi2ps,
UD_Icvtpi2pd,
UD_Icvtps2dq,
UD_Icvtps2pi,
UD_Icvtps2pd,
UD_Icvtsd2si,
UD_Icvtsd2ss,
UD_Icvtsi2ss,
UD_Icvtss2si,
UD_Icvtss2sd,
UD_Icvttpd2pi,
UD_Icvttpd2dq,
UD_Icvttps2dq,
UD_Icvttps2pi,
UD_Icvttsd2si,
UD_Icvtsi2sd,
UD_Icvttss2si,
UD_Icwd,
UD_Icdq,
UD_Icqo,
UD_Idaa,
UD_Idas,
UD_Idec,
UD_Idiv,
UD_Idivpd,
UD_Idivps,
UD_Idivsd,
UD_Idivss,
UD_Iemms,
UD_Ienter,
UD_If2xm1,
UD_Ifabs,
UD_Ifadd,
UD_Ifaddp,
UD_Ifbld,
UD_Ifbstp,
UD_Ifchs,
UD_Ifclex,
UD_Ifcmovb,
UD_Ifcmove,
UD_Ifcmovbe,
UD_Ifcmovu,
UD_Ifcmovnb,
UD_Ifcmovne,
UD_Ifcmovnbe,
UD_Ifcmovnu,
UD_Ifucomi,
UD_Ifcom,
UD_Ifcom2,
UD_Ifcomp3,
UD_Ifcomi,
UD_Ifucomip,
UD_Ifcomip,
UD_Ifcomp,
UD_Ifcomp5,
UD_Ifcompp,
UD_Ifcos,
UD_Ifdecstp,
UD_Ifdiv,
UD_Ifdivp,
UD_Ifdivr,
UD_Ifdivrp,
UD_Ifemms,
UD_Iffree,
UD_Iffreep,
UD_Ificom,
UD_Ificomp,
UD_Ifild,
UD_Ifincstp,
UD_Ifninit,
UD_Ifiadd,
UD_Ifidivr,
UD_Ifidiv,
UD_Ifisub,
UD_Ifisubr,
UD_Ifist,
UD_Ifistp,
UD_Ifisttp,
UD_Ifld,
UD_Ifld1,
UD_Ifldl2t,
UD_Ifldl2e,
UD_Ifldpi,
UD_Ifldlg2,
UD_Ifldln2,
UD_Ifldz,
UD_Ifldcw,
UD_Ifldenv,
UD_Ifmul,
UD_Ifmulp,
UD_Ifimul,
UD_Ifnop,
UD_Ifpatan,
UD_Ifprem,
UD_Ifprem1,
UD_Ifptan,
UD_Ifrndint,
UD_Ifrstor,
UD_Ifnsave,
UD_Ifscale,
UD_Ifsin,
UD_Ifsincos,
UD_Ifsqrt,
UD_Ifstp,
UD_Ifstp1,
UD_Ifstp8,
UD_Ifstp9,
UD_Ifst,
UD_Ifnstcw,
UD_Ifnstenv,
UD_Ifnstsw,
UD_Ifsub,
UD_Ifsubp,
UD_Ifsubr,
UD_Ifsubrp,
UD_Iftst,
UD_Ifucom,
UD_Ifucomp,
UD_Ifucompp,
UD_Ifxam,
UD_Ifxch,
UD_Ifxch4,
UD_Ifxch7,
UD_Ifxrstor,
UD_Ifxsave,
UD_Ifxtract,
UD_Ifyl2x,
UD_Ifyl2xp1,
UD_Ihlt,
UD_Iidiv,
UD_Iin,
UD_Iimul,
UD_Iinc,
UD_Iinsb,
UD_Iinsw,
UD_Iinsd,
UD_Iint1,
UD_Iint3,
UD_Iint,
UD_Iinto,
UD_Iinvd,
UD_Iinvept,
UD_Iinvlpg,
UD_Iinvlpga,
UD_Iinvvpid,
UD_Iiretw,
UD_Iiretd,
UD_Iiretq,
UD_Ijo,
UD_Ijno,
UD_Ijb,
UD_Ijae,
UD_Ijz,
UD_Ijnz,
UD_Ijbe,
UD_Ija,
UD_Ijs,
UD_Ijns,
UD_Ijp,
UD_Ijnp,
UD_Ijl,
UD_Ijge,
UD_Ijle,
UD_Ijg,
UD_Ijcxz,
UD_Ijecxz,
UD_Ijrcxz,
UD_Ijmp,
UD_Ilahf,
UD_Ilar,
UD_Ilddqu,
UD_Ildmxcsr,
UD_Ilds,
UD_Ilea,
UD_Iles,
UD_Ilfs,
UD_Ilgs,
UD_Ilidt,
UD_Ilss,
UD_Ileave,
UD_Ilfence,
UD_Ilgdt,
UD_Illdt,
UD_Ilmsw,
UD_Ilock,
UD_Ilodsb,
UD_Ilodsw,
UD_Ilodsd,
UD_Ilodsq,
UD_Iloopne,
UD_Iloope,
UD_Iloop,
UD_Ilsl,
UD_Iltr,
UD_Imaskmovq,
UD_Imaxpd,
UD_Imaxps,
UD_Imaxsd,
UD_Imaxss,
UD_Imfence,
UD_Iminpd,
UD_Iminps,
UD_Iminsd,
UD_Iminss,
UD_Imonitor,
UD_Imontmul,
UD_Imov,
UD_Imovapd,
UD_Imovaps,
UD_Imovd,
UD_Imovhpd,
UD_Imovhps,
UD_Imovlhps,
UD_Imovlpd,
UD_Imovlps,
UD_Imovhlps,
UD_Imovmskpd,
UD_Imovmskps,
UD_Imovntdq,
UD_Imovnti,
UD_Imovntpd,
UD_Imovntps,
UD_Imovntq,
UD_Imovq,
UD_Imovsb,
UD_Imovsw,
UD_Imovsd,
UD_Imovsq,
UD_Imovss,
UD_Imovsx,
UD_Imovupd,
UD_Imovups,
UD_Imovzx,
UD_Imul,
UD_Imulpd,
UD_Imulps,
UD_Imulsd,
UD_Imulss,
UD_Imwait,
UD_Ineg,
UD_Inop,
UD_Inot,
UD_Ior,
UD_Iorpd,
UD_Iorps,
UD_Iout,
UD_Ioutsb,
UD_Ioutsw,
UD_Ioutsd,
UD_Ipacksswb,
UD_Ipackssdw,
UD_Ipackuswb,
UD_Ipaddb,
UD_Ipaddw,
UD_Ipaddd,
UD_Ipaddsb,
UD_Ipaddsw,
UD_Ipaddusb,
UD_Ipaddusw,
UD_Ipand,
UD_Ipandn,
UD_Ipavgb,
UD_Ipavgw,
UD_Ipcmpeqb,
UD_Ipcmpeqw,
UD_Ipcmpeqd,
UD_Ipcmpgtb,
UD_Ipcmpgtw,
UD_Ipcmpgtd,
UD_Ipextrb,
UD_Ipextrd,
UD_Ipextrq,
UD_Ipextrw,
UD_Ipinsrb,
UD_Ipinsrw,
UD_Ipinsrd,
UD_Ipinsrq,
UD_Ipmaddwd,
UD_Ipmaxsw,
UD_Ipmaxub,
UD_Ipminsw,
UD_Ipminub,
UD_Ipmovmskb,
UD_Ipmulhuw,
UD_Ipmulhw,
UD_Ipmullw,
UD_Ipop,
UD_Ipopa,
UD_Ipopad,
UD_Ipopfw,
UD_Ipopfd,
UD_Ipopfq,
UD_Ipor,
UD_Iprefetch,
UD_Iprefetchnta,
UD_Iprefetcht0,
UD_Iprefetcht1,
UD_Iprefetcht2,
UD_Ipsadbw,
UD_Ipshufw,
UD_Ipsllw,
UD_Ipslld,
UD_Ipsllq,
UD_Ipsraw,
UD_Ipsrad,
UD_Ipsrlw,
UD_Ipsrld,
UD_Ipsrlq,
UD_Ipsubb,
UD_Ipsubw,
UD_Ipsubd,
UD_Ipsubsb,
UD_Ipsubsw,
UD_Ipsubusb,
UD_Ipsubusw,
UD_Ipunpckhbw,
UD_Ipunpckhwd,
UD_Ipunpckhdq,
UD_Ipunpcklbw,
UD_Ipunpcklwd,
UD_Ipunpckldq,
UD_Ipi2fw,
UD_Ipi2fd,
UD_Ipf2iw,
UD_Ipf2id,
UD_Ipfnacc,
UD_Ipfpnacc,
UD_Ipfcmpge,
UD_Ipfmin,
UD_Ipfrcp,
UD_Ipfrsqrt,
UD_Ipfsub,
UD_Ipfadd,
UD_Ipfcmpgt,
UD_Ipfmax,
UD_Ipfrcpit1,
UD_Ipfrsqit1,
UD_Ipfsubr,
UD_Ipfacc,
UD_Ipfcmpeq,
UD_Ipfmul,
UD_Ipfrcpit2,
UD_Ipmulhrw,
UD_Ipswapd,
UD_Ipavgusb,
UD_Ipush,
UD_Ipusha,
UD_Ipushad,
UD_Ipushfw,
UD_Ipushfd,
UD_Ipushfq,
UD_Ipxor,
UD_Ircl,
UD_Ircr,
UD_Irol,
UD_Iror,
UD_Ircpps,
UD_Ircpss,
UD_Irdmsr,
UD_Irdpmc,
UD_Irdtsc,
UD_Irdtscp,
UD_Irepne,
UD_Irep,
UD_Iret,
UD_Iretf,
UD_Irsm,
UD_Irsqrtps,
UD_Irsqrtss,
UD_Isahf,
UD_Isalc,
UD_Isar,
UD_Ishl,
UD_Ishr,
UD_Isbb,
UD_Iscasb,
UD_Iscasw,
UD_Iscasd,
UD_Iscasq,
UD_Iseto,
UD_Isetno,
UD_Isetb,
UD_Isetae,
UD_Isetz,
UD_Isetnz,
UD_Isetbe,
UD_Iseta,
UD_Isets,
UD_Isetns,
UD_Isetp,
UD_Isetnp,
UD_Isetl,
UD_Isetge,
UD_Isetle,
UD_Isetg,
UD_Isfence,
UD_Isgdt,
UD_Ishld,
UD_Ishrd,
UD_Ishufpd,
UD_Ishufps,
UD_Isidt,
UD_Isldt,
UD_Ismsw,
UD_Isqrtps,
UD_Isqrtpd,
UD_Isqrtsd,
UD_Isqrtss,
UD_Istc,
UD_Istd,
UD_Istgi,
UD_Isti,
UD_Iskinit,
UD_Istmxcsr,
UD_Istosb,
UD_Istosw,
UD_Istosd,
UD_Istosq,
UD_Istr,
UD_Isub,
UD_Isubpd,
UD_Isubps,
UD_Isubsd,
UD_Isubss,
UD_Iswapgs,
UD_Isyscall,
UD_Isysenter,
UD_Isysexit,
UD_Isysret,
UD_Itest,
UD_Iucomisd,
UD_Iucomiss,
UD_Iud2,
UD_Iunpckhpd,
UD_Iunpckhps,
UD_Iunpcklps,
UD_Iunpcklpd,
UD_Iverr,
UD_Iverw,
UD_Ivmcall,
UD_Ivmclear,
UD_Ivmxon,
UD_Ivmptrld,
UD_Ivmptrst,
UD_Ivmlaunch,
UD_Ivmresume,
UD_Ivmxoff,
UD_Ivmread,
UD_Ivmwrite,
UD_Ivmrun,
UD_Ivmmcall,
UD_Ivmload,
UD_Ivmsave,
UD_Iwait,
UD_Iwbinvd,
UD_Iwrmsr,
UD_Ixadd,
UD_Ixchg,
UD_Ixgetbv,
UD_Ixlatb,
UD_Ixor,
UD_Ixorpd,
UD_Ixorps,
UD_Ixcryptecb,
UD_Ixcryptcbc,
UD_Ixcryptctr,
UD_Ixcryptcfb,
UD_Ixcryptofb,
UD_Ixrstor,
UD_Ixsave,
UD_Ixsetbv,
UD_Ixsha1,
UD_Ixsha256,
UD_Ixstore,
UD_Iaesdec,
UD_Iaesdeclast,
UD_Iaesenc,
UD_Iaesenclast,
UD_Iaesimc,
UD_Iaeskeygenassist,
UD_Ipclmulqdq,
UD_Igetsec,
UD_Imovdqa,
UD_Imaskmovdqu,
UD_Imovdq2q,
UD_Imovdqu,
UD_Imovq2dq,
UD_Ipaddq,
UD_Ipsubq,
UD_Ipmuludq,
UD_Ipshufhw,
UD_Ipshuflw,
UD_Ipshufd,
UD_Ipslldq,
UD_Ipsrldq,
UD_Ipunpckhqdq,
UD_Ipunpcklqdq,
UD_Iaddsubpd,
UD_Iaddsubps,
UD_Ihaddpd,
UD_Ihaddps,
UD_Ihsubpd,
UD_Ihsubps,
UD_Imovddup,
UD_Imovshdup,
UD_Imovsldup,
UD_Ipabsb,
UD_Ipabsw,
UD_Ipabsd,
UD_Ipshufb,
UD_Iphaddw,
UD_Iphaddd,
UD_Iphaddsw,
UD_Ipmaddubsw,
UD_Iphsubw,
UD_Iphsubd,
UD_Iphsubsw,
UD_Ipsignb,
UD_Ipsignd,
UD_Ipsignw,
UD_Ipmulhrsw,
UD_Ipalignr,
UD_Ipblendvb,
UD_Ipmuldq,
UD_Ipminsb,
UD_Ipminsd,
UD_Ipminuw,
UD_Ipminud,
UD_Ipmaxsb,
UD_Ipmaxsd,
UD_Ipmaxud,
UD_Ipmaxuw,
UD_Ipmulld,
UD_Iphminposuw,
UD_Iroundps,
UD_Iroundpd,
UD_Iroundss,
UD_Iroundsd,
UD_Iblendpd,
UD_Ipblendw,
UD_Iblendps,
UD_Iblendvpd,
UD_Iblendvps,
UD_Idpps,
UD_Idppd,
UD_Impsadbw,
UD_Iextractps,
UD_Iinsertps,
UD_Imovntdqa,
UD_Ipackusdw,
UD_Ipmovsxbw,
UD_Ipmovsxbd,
UD_Ipmovsxbq,
UD_Ipmovsxwd,
UD_Ipmovsxwq,
UD_Ipmovsxdq,
UD_Ipmovzxbw,
UD_Ipmovzxbd,
UD_Ipmovzxbq,
UD_Ipmovzxwd,
UD_Ipmovzxwq,
UD_Ipmovzxdq,
UD_Ipcmpeqq,
UD_Ipopcnt,
UD_Iptest,
UD_Ipcmpestri,
UD_Ipcmpestrm,
UD_Ipcmpgtq,
UD_Ipcmpistri,
UD_Ipcmpistrm,
UD_Imovbe,
UD_Icrc32,
UD_MAX_MNEMONIC_CODE
} UD_ATTR_PACKED;
extern const char * ud_mnemonics_str[];
#endif /* UD_ITAB_H */

224
public/libudis86/syn-att.c Normal file
View File

@ -0,0 +1,224 @@
/* udis86 - libudis86/syn-att.c
*
* Copyright (c) 2002-2009 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "types.h"
#include "extern.h"
#include "decode.h"
#include "itab.h"
#include "syn.h"
#include "udint.h"
/* -----------------------------------------------------------------------------
* opr_cast() - Prints an operand cast.
* -----------------------------------------------------------------------------
*/
static void
opr_cast(struct ud* u, struct ud_operand* op)
{
switch(op->size) {
case 16 : case 32 :
ud_asmprintf(u, "*"); break;
default: break;
}
}
/* -----------------------------------------------------------------------------
* gen_operand() - Generates assembly output for each operand.
* -----------------------------------------------------------------------------
*/
static void
gen_operand(struct ud* u, struct ud_operand* op)
{
switch(op->type) {
case UD_OP_CONST:
ud_asmprintf(u, "$0x%x", op->lval.udword);
break;
case UD_OP_REG:
ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
break;
case UD_OP_MEM:
if (u->br_far) {
opr_cast(u, op);
}
if (u->pfx_seg) {
ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
}
if (op->offset != 0) {
ud_syn_print_mem_disp(u, op, 0);
}
if (op->base) {
ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
}
if (op->index) {
if (op->base) {
ud_asmprintf(u, ",");
} else {
ud_asmprintf(u, "(");
}
ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
}
if (op->scale) {
ud_asmprintf(u, ",%d", op->scale);
}
if (op->base || op->index) {
ud_asmprintf(u, ")");
}
break;
case UD_OP_IMM:
ud_asmprintf(u, "$");
ud_syn_print_imm(u, op);
break;
case UD_OP_JIMM:
ud_syn_print_addr(u, ud_syn_rel_target(u, op));
break;
case UD_OP_PTR:
switch (op->size) {
case 32:
ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
op->lval.ptr.off & 0xFFFF);
break;
case 48:
ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
op->lval.ptr.off);
break;
}
break;
default: return;
}
}
/* =============================================================================
* translates to AT&T syntax
* =============================================================================
*/
extern void
ud_translate_att(struct ud *u)
{
int size = 0;
int star = 0;
/* check if P_OSO prefix is used */
if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
switch (u->dis_mode) {
case 16:
ud_asmprintf(u, "o32 ");
break;
case 32:
case 64:
ud_asmprintf(u, "o16 ");
break;
}
}
/* check if P_ASO prefix was used */
if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
switch (u->dis_mode) {
case 16:
ud_asmprintf(u, "a32 ");
break;
case 32:
ud_asmprintf(u, "a16 ");
break;
case 64:
ud_asmprintf(u, "a32 ");
break;
}
}
if (u->pfx_lock)
ud_asmprintf(u, "lock ");
if (u->pfx_rep) {
ud_asmprintf(u, "rep ");
} else if (u->pfx_rep) {
ud_asmprintf(u, "repe ");
} else if (u->pfx_repne) {
ud_asmprintf(u, "repne ");
}
/* special instructions */
switch (u->mnemonic) {
case UD_Iretf:
ud_asmprintf(u, "lret ");
break;
case UD_Idb:
ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte);
return;
case UD_Ijmp:
case UD_Icall:
if (u->br_far) ud_asmprintf(u, "l");
if (u->operand[0].type == UD_OP_REG) {
star = 1;
}
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
break;
case UD_Ibound:
case UD_Ienter:
if (u->operand[0].type != UD_NONE)
gen_operand(u, &u->operand[0]);
if (u->operand[1].type != UD_NONE) {
ud_asmprintf(u, ",");
gen_operand(u, &u->operand[1]);
}
return;
default:
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
}
if (size == 8)
ud_asmprintf(u, "b");
else if (size == 16)
ud_asmprintf(u, "w");
else if (size == 64)
ud_asmprintf(u, "q");
if (star) {
ud_asmprintf(u, " *");
} else {
ud_asmprintf(u, " ");
}
if (u->operand[2].type != UD_NONE) {
gen_operand(u, &u->operand[2]);
ud_asmprintf(u, ", ");
}
if (u->operand[1].type != UD_NONE) {
gen_operand(u, &u->operand[1]);
ud_asmprintf(u, ", ");
}
if (u->operand[0].type != UD_NONE)
gen_operand(u, &u->operand[0]);
}
/*
vim: set ts=2 sw=2 expandtab
*/

View File

@ -0,0 +1,213 @@
/* udis86 - libudis86/syn-intel.c
*
* Copyright (c) 2002-2013 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "types.h"
#include "extern.h"
#include "decode.h"
#include "itab.h"
#include "syn.h"
#include "udint.h"
/* -----------------------------------------------------------------------------
* opr_cast() - Prints an operand cast.
* -----------------------------------------------------------------------------
*/
static void
opr_cast(struct ud* u, struct ud_operand* op)
{
if (u->br_far) {
ud_asmprintf(u, "far ");
}
switch(op->size) {
case 8: ud_asmprintf(u, "byte " ); break;
case 16: ud_asmprintf(u, "word " ); break;
case 32: ud_asmprintf(u, "dword "); break;
case 64: ud_asmprintf(u, "qword "); break;
case 80: ud_asmprintf(u, "tword "); break;
default: break;
}
}
/* -----------------------------------------------------------------------------
* gen_operand() - Generates assembly output for each operand.
* -----------------------------------------------------------------------------
*/
static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
{
switch(op->type) {
case UD_OP_REG:
ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
break;
case UD_OP_MEM:
if (syn_cast) {
opr_cast(u, op);
}
ud_asmprintf(u, "[");
if (u->pfx_seg) {
ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
}
if (op->base) {
ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
}
if (op->index) {
ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "",
ud_reg_tab[op->index - UD_R_AL]);
if (op->scale) {
ud_asmprintf(u, "*%d", op->scale);
}
}
if (op->offset != 0) {
ud_syn_print_mem_disp(u, op, (op->base != UD_NONE ||
op->index != UD_NONE) ? 1 : 0);
}
ud_asmprintf(u, "]");
break;
case UD_OP_IMM:
ud_syn_print_imm(u, op);
break;
case UD_OP_JIMM:
ud_syn_print_addr(u, ud_syn_rel_target(u, op));
break;
case UD_OP_PTR:
switch (op->size) {
case 32:
ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg,
op->lval.ptr.off & 0xFFFF);
break;
case 48:
ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg,
op->lval.ptr.off);
break;
}
break;
case UD_OP_CONST:
if (syn_cast) opr_cast(u, op);
ud_asmprintf(u, "%d", op->lval.udword);
break;
default: return;
}
}
/* =============================================================================
* translates to intel syntax
* =============================================================================
*/
extern void
ud_translate_intel(struct ud* u)
{
/* check if P_OSO prefix is used */
if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
switch (u->dis_mode) {
case 16: ud_asmprintf(u, "o32 "); break;
case 32:
case 64: ud_asmprintf(u, "o16 "); break;
}
}
/* check if P_ASO prefix was used */
if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
switch (u->dis_mode) {
case 16: ud_asmprintf(u, "a32 "); break;
case 32: ud_asmprintf(u, "a16 "); break;
case 64: ud_asmprintf(u, "a32 "); break;
}
}
if (u->pfx_seg &&
u->operand[0].type != UD_OP_MEM &&
u->operand[1].type != UD_OP_MEM ) {
ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
}
if (u->pfx_lock) {
ud_asmprintf(u, "lock ");
}
if (u->pfx_rep) {
ud_asmprintf(u, "rep ");
} else if (u->pfx_repe) {
ud_asmprintf(u, "repe ");
} else if (u->pfx_repne) {
ud_asmprintf(u, "repne ");
}
/* print the instruction mnemonic */
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
if (u->operand[0].type != UD_NONE) {
int cast = 0;
ud_asmprintf(u, " ");
if (u->operand[0].type == UD_OP_MEM) {
if (u->operand[1].type == UD_OP_IMM ||
u->operand[1].type == UD_OP_CONST ||
u->operand[1].type == UD_NONE ||
(u->operand[0].size != u->operand[1].size &&
u->operand[1].type != UD_OP_REG)) {
cast = 1;
} else if (u->operand[1].type == UD_OP_REG &&
u->operand[1].base == UD_R_CL) {
switch (u->mnemonic) {
case UD_Ircl:
case UD_Irol:
case UD_Iror:
case UD_Ircr:
case UD_Ishl:
case UD_Ishr:
case UD_Isar:
cast = 1;
break;
default: break;
}
}
}
gen_operand(u, &u->operand[0], cast);
}
if (u->operand[1].type != UD_NONE) {
int cast = 0;
ud_asmprintf(u, ", ");
if (u->operand[1].type == UD_OP_MEM &&
u->operand[0].size != u->operand[1].size &&
!ud_opr_is_sreg(&u->operand[0])) {
cast = 1;
}
gen_operand(u, &u->operand[1], cast);
}
if (u->operand[2].type != UD_NONE) {
ud_asmprintf(u, ", ");
gen_operand(u, &u->operand[2], 0);
}
}
/*
vim: set ts=2 sw=2 expandtab
*/

207
public/libudis86/syn.c Normal file
View File

@ -0,0 +1,207 @@
/* udis86 - libudis86/syn.c
*
* Copyright (c) 2002-2013 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "types.h"
#include "decode.h"
#include "syn.h"
#include "udint.h"
/* -----------------------------------------------------------------------------
* Intel Register Table - Order Matters (types.h)!
* -----------------------------------------------------------------------------
*/
const char* ud_reg_tab[] =
{
"al", "cl", "dl", "bl",
"ah", "ch", "dh", "bh",
"spl", "bpl", "sil", "dil",
"r8b", "r9b", "r10b", "r11b",
"r12b", "r13b", "r14b", "r15b",
"ax", "cx", "dx", "bx",
"sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w",
"r12w", "r13w" , "r14w", "r15w",
"eax", "ecx", "edx", "ebx",
"esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d",
"r12d", "r13d", "r14d", "r15d",
"rax", "rcx", "rdx", "rbx",
"rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11",
"r12", "r13", "r14", "r15",
"es", "cs", "ss", "ds",
"fs", "gs",
"cr0", "cr1", "cr2", "cr3",
"cr4", "cr5", "cr6", "cr7",
"cr8", "cr9", "cr10", "cr11",
"cr12", "cr13", "cr14", "cr15",
"dr0", "dr1", "dr2", "dr3",
"dr4", "dr5", "dr6", "dr7",
"dr8", "dr9", "dr10", "dr11",
"dr12", "dr13", "dr14", "dr15",
"mm0", "mm1", "mm2", "mm3",
"mm4", "mm5", "mm6", "mm7",
"st0", "st1", "st2", "st3",
"st4", "st5", "st6", "st7",
"xmm0", "xmm1", "xmm2", "xmm3",
"xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11",
"xmm12", "xmm13", "xmm14", "xmm15",
"rip"
};
uint64_t
ud_syn_rel_target(struct ud *u, struct ud_operand *opr)
{
const uint64_t trunc_mask = 0xffffffffffffffffull >> (64 - u->opr_mode);
switch (opr->size) {
case 8 : return (u->pc + opr->lval.sbyte) & trunc_mask;
case 16: return (u->pc + opr->lval.sword) & trunc_mask;
case 32: return (u->pc + opr->lval.sdword) & trunc_mask;
default: UD_ASSERT(!"invalid relative offset size.");
return 0ull;
}
}
/*
* asmprintf
* Printf style function for printing translated assembly
* output. Returns the number of characters written and
* moves the buffer pointer forward. On an overflow,
* returns a negative number and truncates the output.
*/
int
ud_asmprintf(struct ud *u, const char *fmt, ...)
{
int ret;
int avail;
va_list ap;
va_start(ap, fmt);
avail = u->asm_buf_size - u->asm_buf_fill - 1 /* nullchar */;
ret = vsnprintf((char*) u->asm_buf + u->asm_buf_fill, avail, fmt, ap);
if (ret < 0 || ret > avail) {
u->asm_buf_fill = u->asm_buf_size - 1;
} else {
u->asm_buf_fill += ret;
}
va_end(ap);
return ret;
}
void
ud_syn_print_addr(struct ud *u, uint64_t addr)
{
const char *name = NULL;
if (u->sym_resolver) {
int64_t offset = 0;
name = u->sym_resolver(u, addr, &offset);
if (name) {
if (offset) {
ud_asmprintf(u, "%s%+" FMT64 "d", name, offset);
} else {
ud_asmprintf(u, "%s", name);
}
return;
}
}
ud_asmprintf(u, "0x%" FMT64 "x", addr);
}
void
ud_syn_print_imm(struct ud* u, const struct ud_operand *op)
{
uint64_t v;
if (op->_oprcode == OP_sI && op->size != u->opr_mode) {
if (op->size == 8) {
v = (int64_t)op->lval.sbyte;
} else {
UD_ASSERT(op->size == 32);
v = (int64_t)op->lval.sdword;
}
if (u->opr_mode < 64) {
v = v & ((1ull << u->opr_mode) - 1ull);
}
} else {
switch (op->size) {
case 8 : v = op->lval.ubyte; break;
case 16: v = op->lval.uword; break;
case 32: v = op->lval.udword; break;
case 64: v = op->lval.uqword; break;
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
}
}
ud_asmprintf(u, "0x%" FMT64 "x", v);
}
void
ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *op, int sign)
{
UD_ASSERT(op->offset != 0);
if (op->base == UD_NONE && op->index == UD_NONE) {
uint64_t v;
UD_ASSERT(op->scale == UD_NONE && op->offset != 8);
/* unsigned mem-offset */
switch (op->offset) {
case 16: v = op->lval.uword; break;
case 32: v = op->lval.udword; break;
case 64: v = op->lval.uqword; break;
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
}
ud_asmprintf(u, "0x%" FMT64 "x", v);
} else {
int64_t v;
UD_ASSERT(op->offset != 64);
switch (op->offset) {
case 8 : v = op->lval.sbyte; break;
case 16: v = op->lval.sword; break;
case 32: v = op->lval.sdword; break;
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
}
if (v < 0) {
ud_asmprintf(u, "-0x%" FMT64 "x", -v);
} else if (v > 0) {
ud_asmprintf(u, "%s0x%" FMT64 "x", sign? "+" : "", v);
}
}
}
/*
vim: set ts=2 sw=2 expandtab
*/

53
public/libudis86/syn.h Normal file
View File

@ -0,0 +1,53 @@
/* udis86 - libudis86/syn.h
*
* Copyright (c) 2002-2009
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UD_SYN_H
#define UD_SYN_H
#include "types.h"
#ifndef __UD_STANDALONE__
# include <stdarg.h>
#endif /* __UD_STANDALONE__ */
extern const char* ud_reg_tab[];
uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*);
#ifdef __GNUC__
int ud_asmprintf(struct ud *u, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
#else
int ud_asmprintf(struct ud *u, const char *fmt, ...);
#endif
void ud_syn_print_addr(struct ud *u, uint64_t addr);
void ud_syn_print_imm(struct ud* u, const struct ud_operand *op);
void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign);
#endif /* UD_SYN_H */
/*
vim: set ts=2 sw=2 expandtab
*/

250
public/libudis86/types.h Normal file
View File

@ -0,0 +1,250 @@
/* udis86 - libudis86/types.h
*
* Copyright (c) 2002-2013 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UD_TYPES_H
#define UD_TYPES_H
#ifdef __KERNEL__
/* -D__KERNEL__ is automatically passed on the command line when
building something as part of the Linux kernel */
# include <linux/kernel.h>
# include <linux/string.h>
# ifndef __UD_STANDALONE__
# define __UD_STANDALONE__ 1
#endif
#endif /* __KERNEL__ */
#if defined(_MSC_VER) || defined(__BORLANDC__)
# include <stdint.h>
# include <stdio.h>
# define inline __inline /* MS Visual Studio requires __inline
instead of inline for C code */
#elif !defined(__UD_STANDALONE__)
# include <stdio.h>
# include <inttypes.h>
#endif /* !__UD_STANDALONE__ */
/* gcc specific extensions */
#ifdef __GNUC__
# define UD_ATTR_PACKED __attribute__((packed))
#else
# define UD_ATTR_PACKED
#endif /* UD_ATTR_PACKED */
/* -----------------------------------------------------------------------------
* All possible "types" of objects in udis86. Order is Important!
* -----------------------------------------------------------------------------
*/
enum ud_type
{
UD_NONE,
/* 8 bit GPRs */
UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL,
UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH,
UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL,
UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B,
UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B,
/* 16 bit GPRs */
UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX,
UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI,
UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W,
UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W,
/* 32 bit GPRs */
UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX,
UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI,
UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D,
UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D,
/* 64 bit GPRs */
UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX,
UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI,
UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11,
UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15,
/* segment registers */
UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS,
UD_R_FS, UD_R_GS,
/* control registers*/
UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3,
UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7,
UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11,
UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15,
/* debug registers */
UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3,
UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7,
UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11,
UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15,
/* mmx registers */
UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3,
UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7,
/* x87 registers */
UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3,
UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7,
/* extended multimedia registers */
UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3,
UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7,
UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11,
UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15,
UD_R_RIP,
/* Operand Types */
UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM,
UD_OP_JIMM, UD_OP_CONST
};
#include "itab.h"
union ud_lval {
int8_t sbyte;
uint8_t ubyte;
int16_t sword;
uint16_t uword;
int32_t sdword;
uint32_t udword;
int64_t sqword;
uint64_t uqword;
struct {
uint16_t seg;
uint32_t off;
} ptr;
};
/* -----------------------------------------------------------------------------
* struct ud_operand - Disassembled instruction Operand.
* -----------------------------------------------------------------------------
*/
struct ud_operand {
enum ud_type type;
uint8_t size;
enum ud_type base;
enum ud_type index;
uint8_t scale;
uint8_t offset;
union ud_lval lval;
/*
* internal use only
*/
uint64_t _legacy; /* this will be removed in 1.8 */
uint8_t _oprcode;
};
/* -----------------------------------------------------------------------------
* struct ud - The udis86 object.
* -----------------------------------------------------------------------------
*/
struct ud
{
/*
* input buffering
*/
int (*inp_hook) (struct ud*);
#ifndef __UD_STANDALONE__
FILE* inp_file;
#endif
const uint8_t* inp_buf;
size_t inp_buf_size;
size_t inp_buf_index;
uint8_t inp_curr;
size_t inp_ctr;
uint8_t inp_sess[64];
int inp_end;
void (*translator)(struct ud*);
uint64_t insn_offset;
char insn_hexcode[64];
/*
* Assembly output buffer
*/
char *asm_buf;
size_t asm_buf_size;
size_t asm_buf_fill;
char asm_buf_int[128];
/*
* Symbol resolver for use in the translation phase.
*/
const char* (*sym_resolver)(struct ud*, uint64_t addr, int64_t *offset);
uint8_t dis_mode;
uint64_t pc;
uint8_t vendor;
enum ud_mnemonic_code mnemonic;
struct ud_operand operand[3];
uint8_t error;
uint8_t pfx_rex;
uint8_t pfx_seg;
uint8_t pfx_opr;
uint8_t pfx_adr;
uint8_t pfx_lock;
uint8_t pfx_str;
uint8_t pfx_rep;
uint8_t pfx_repe;
uint8_t pfx_repne;
uint8_t opr_mode;
uint8_t adr_mode;
uint8_t br_far;
uint8_t br_near;
uint8_t have_modrm;
uint8_t modrm;
uint8_t primary_opcode;
void * user_opaque_data;
struct ud_itab_entry * itab_entry;
struct ud_lookup_table_list_entry *le;
};
/* -----------------------------------------------------------------------------
* Type-definitions
* -----------------------------------------------------------------------------
*/
typedef enum ud_type ud_type_t;
typedef enum ud_mnemonic_code ud_mnemonic_code_t;
typedef struct ud ud_t;
typedef struct ud_operand ud_operand_t;
#define UD_SYN_INTEL ud_translate_intel
#define UD_SYN_ATT ud_translate_att
#define UD_EOI (-1)
#define UD_INP_CACHE_SZ 32
#define UD_VENDOR_AMD 0
#define UD_VENDOR_INTEL 1
#define UD_VENDOR_ANY 2
#endif
/*
vim: set ts=2 sw=2 expandtab
*/

89
public/libudis86/udint.h Normal file
View File

@ -0,0 +1,89 @@
/* udis86 - libudis86/udint.h -- definitions for internal use only
*
* Copyright (c) 2002-2009 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _UDINT_H_
#define _UDINT_H_
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#if defined(UD_DEBUG) && HAVE_ASSERT_H
# include <assert.h>
# define UD_ASSERT(_x) assert(_x)
#else
# define UD_ASSERT(_x)
#endif /* !HAVE_ASSERT_H */
#if defined(UD_DEBUG)
#define UDERR(u, msg) \
do { \
(u)->error = 1; \
fprintf(stderr, "decode-error: %s:%d: %s", \
__FILE__, __LINE__, (msg)); \
} while (0)
#else
#define UDERR(u, m) \
do { \
(u)->error = 1; \
} while (0)
#endif /* !LOGERR */
#define UD_RETURN_ON_ERROR(u) \
do { \
if ((u)->error != 0) { \
return (u)->error; \
} \
} while (0)
#define UD_RETURN_WITH_ERROR(u, m) \
do { \
UDERR(u, m); \
return (u)->error; \
} while (0)
#ifndef __UD_STANDALONE__
# define UD_NON_STANDALONE(x) x
#else
# define UD_NON_STANDALONE(x)
#endif
/* printf formatting int64 specifier */
#ifdef FMT64
# undef FMT64
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__)
# define FMT64 "I64"
#else
# if defined(__APPLE__)
# define FMT64 "ll"
# elif defined(__amd64__) || defined(__x86_64__)
# define FMT64 "l"
# else
# define FMT64 "ll"
# endif /* !x64 */
#endif
#endif /* _UDINT_H_ */

457
public/libudis86/udis86.c Normal file
View File

@ -0,0 +1,457 @@
/* udis86 - libudis86/udis86.c
*
* Copyright (c) 2002-2013 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "udint.h"
#include "extern.h"
#include "decode.h"
#if !defined(__UD_STANDALONE__)
# if HAVE_STRING_H
# include <string.h>
# endif
#endif /* !__UD_STANDALONE__ */
static void ud_inp_init(struct ud *u);
/* =============================================================================
* ud_init
* Initializes ud_t object.
* =============================================================================
*/
extern void
ud_init(struct ud* u)
{
memset((void*)u, 0, sizeof(struct ud));
ud_set_mode(u, 16);
u->mnemonic = UD_Iinvalid;
ud_set_pc(u, 0);
#ifndef __UD_STANDALONE__
ud_set_input_file(u, stdin);
#endif /* __UD_STANDALONE__ */
ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
}
/* =============================================================================
* ud_disassemble
* Disassembles one instruction and returns the number of
* bytes disassembled. A zero means end of disassembly.
* =============================================================================
*/
extern unsigned int
ud_disassemble(struct ud* u)
{
int len;
if (u->inp_end) {
return 0;
}
if ((len = ud_decode(u)) > 0) {
if (u->translator != NULL) {
u->asm_buf[0] = '\0';
u->translator(u);
}
}
return len;
}
/* =============================================================================
* ud_set_mode() - Set Disassemly Mode.
* =============================================================================
*/
extern void
ud_set_mode(struct ud* u, uint8_t m)
{
switch(m) {
case 16:
case 32:
case 64: u->dis_mode = m ; return;
default: u->dis_mode = 16; return;
}
}
/* =============================================================================
* ud_set_vendor() - Set vendor.
* =============================================================================
*/
extern void
ud_set_vendor(struct ud* u, unsigned v)
{
switch(v) {
case UD_VENDOR_INTEL:
u->vendor = v;
break;
case UD_VENDOR_ANY:
u->vendor = v;
break;
default:
u->vendor = UD_VENDOR_AMD;
}
}
/* =============================================================================
* ud_set_pc() - Sets code origin.
* =============================================================================
*/
extern void
ud_set_pc(struct ud* u, uint64_t o)
{
u->pc = o;
}
/* =============================================================================
* ud_set_syntax() - Sets the output syntax.
* =============================================================================
*/
extern void
ud_set_syntax(struct ud* u, void (*t)(struct ud*))
{
u->translator = t;
}
/* =============================================================================
* ud_insn() - returns the disassembled instruction
* =============================================================================
*/
const char*
ud_insn_asm(const struct ud* u)
{
return u->asm_buf;
}
/* =============================================================================
* ud_insn_offset() - Returns the offset.
* =============================================================================
*/
uint64_t
ud_insn_off(const struct ud* u)
{
return u->insn_offset;
}
/* =============================================================================
* ud_insn_hex() - Returns hex form of disassembled instruction.
* =============================================================================
*/
const char*
ud_insn_hex(struct ud* u)
{
u->insn_hexcode[0] = 0;
if (!u->error) {
unsigned int i;
const unsigned char *src_ptr = ud_insn_ptr(u);
char* src_hex;
src_hex = (char*) u->insn_hexcode;
/* for each byte used to decode instruction */
for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2;
++i, ++src_ptr) {
sprintf(src_hex, "%02x", *src_ptr & 0xFF);
src_hex += 2;
}
}
return u->insn_hexcode;
}
/* =============================================================================
* ud_insn_ptr
* Returns a pointer to buffer containing the bytes that were
* disassembled.
* =============================================================================
*/
extern const uint8_t*
ud_insn_ptr(const struct ud* u)
{
return (u->inp_buf == NULL) ?
u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr);
}
/* =============================================================================
* ud_insn_len
* Returns the count of bytes disassembled.
* =============================================================================
*/
extern unsigned int
ud_insn_len(const struct ud* u)
{
return u->inp_ctr;
}
/* =============================================================================
* ud_insn_get_opr
* Return the operand struct representing the nth operand of
* the currently disassembled instruction. Returns NULL if
* there's no such operand.
* =============================================================================
*/
const struct ud_operand*
ud_insn_opr(const struct ud *u, unsigned int n)
{
if (n > 2 || u->operand[n].type == UD_NONE) {
return NULL;
} else {
return &u->operand[n];
}
}
/* =============================================================================
* ud_opr_is_sreg
* Returns non-zero if the given operand is of a segment register type.
* =============================================================================
*/
int
ud_opr_is_sreg(const struct ud_operand *opr)
{
return opr->type == UD_OP_REG &&
opr->base >= UD_R_ES &&
opr->base <= UD_R_GS;
}
/* =============================================================================
* ud_opr_is_sreg
* Returns non-zero if the given operand is of a general purpose
* register type.
* =============================================================================
*/
int
ud_opr_is_gpr(const struct ud_operand *opr)
{
return opr->type == UD_OP_REG &&
opr->base >= UD_R_AL &&
opr->base <= UD_R_R15;
}
/* =============================================================================
* ud_set_user_opaque_data
* ud_get_user_opaque_data
* Get/set user opaqute data pointer
* =============================================================================
*/
void
ud_set_user_opaque_data(struct ud * u, void* opaque)
{
u->user_opaque_data = opaque;
}
void*
ud_get_user_opaque_data(const struct ud *u)
{
return u->user_opaque_data;
}
/* =============================================================================
* ud_set_asm_buffer
* Allow the user to set an assembler output buffer. If `buf` is NULL,
* we switch back to the internal buffer.
* =============================================================================
*/
void
ud_set_asm_buffer(struct ud *u, char *buf, size_t size)
{
if (buf == NULL) {
ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
} else {
u->asm_buf = buf;
u->asm_buf_size = size;
}
}
/* =============================================================================
* ud_set_sym_resolver
* Set symbol resolver for relative targets used in the translation
* phase.
*
* The resolver is a function that takes a uint64_t address and returns a
* symbolic name for the that address. The function also takes a second
* argument pointing to an integer that the client can optionally set to a
* non-zero value for offsetted targets. (symbol+offset) The function may
* also return NULL, in which case the translator only prints the target
* address.
*
* The function pointer maybe NULL which resets symbol resolution.
* =============================================================================
*/
void
ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*,
uint64_t addr,
int64_t *offset))
{
u->sym_resolver = resolver;
}
/* =============================================================================
* ud_insn_mnemonic
* Return the current instruction mnemonic.
* =============================================================================
*/
enum ud_mnemonic_code
ud_insn_mnemonic(const struct ud *u)
{
return u->mnemonic;
}
/* =============================================================================
* ud_lookup_mnemonic
* Looks up mnemonic code in the mnemonic string table.
* Returns NULL if the mnemonic code is invalid.
* =============================================================================
*/
const char*
ud_lookup_mnemonic(enum ud_mnemonic_code c)
{
if (c < UD_MAX_MNEMONIC_CODE) {
return ud_mnemonics_str[c];
} else {
return NULL;
}
}
/*
* ud_inp_init
* Initializes the input system.
*/
static void
ud_inp_init(struct ud *u)
{
u->inp_hook = NULL;
u->inp_buf = NULL;
u->inp_buf_size = 0;
u->inp_buf_index = 0;
u->inp_curr = 0;
u->inp_ctr = 0;
u->inp_end = 0;
UD_NON_STANDALONE(u->inp_file = NULL);
}
/* =============================================================================
* ud_inp_set_hook
* Sets input hook.
* =============================================================================
*/
void
ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
{
ud_inp_init(u);
u->inp_hook = hook;
}
/* =============================================================================
* ud_inp_set_buffer
* Set buffer as input.
* =============================================================================
*/
void
ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len)
{
ud_inp_init(u);
u->inp_buf = buf;
u->inp_buf_size = len;
u->inp_buf_index = 0;
}
#ifndef __UD_STANDALONE__
/* =============================================================================
* ud_input_set_file
* Set FILE as input.
* =============================================================================
*/
static int
inp_file_hook(struct ud* u)
{
return fgetc(u->inp_file);
}
void
ud_set_input_file(register struct ud* u, FILE* f)
{
ud_inp_init(u);
u->inp_hook = inp_file_hook;
u->inp_file = f;
}
#endif /* __UD_STANDALONE__ */
/* =============================================================================
* ud_input_skip
* Skip n input bytes.
* ============================================================================
*/
void
ud_input_skip(struct ud* u, size_t n)
{
if (u->inp_end) {
return;
}
if (u->inp_buf == NULL) {
while (n--) {
int c = u->inp_hook(u);
if (c == UD_EOI) {
goto eoi;
}
}
return;
} else {
if (n > u->inp_buf_size ||
u->inp_buf_index > u->inp_buf_size - n) {
u->inp_buf_index = u->inp_buf_size;
goto eoi;
}
u->inp_buf_index += n;
return;
}
eoi:
u->inp_end = 1;
UDERR(u, "cannot skip, eoi received\b");
return;
}
/* =============================================================================
* ud_input_end
* Returns non-zero on end-of-input.
* =============================================================================
*/
int
ud_input_end(const struct ud *u)
{
return u->inp_end;
}
/* vim:set ts=2 sw=2 expandtab */

33
public/libudis86/udis86.h Normal file
View File

@ -0,0 +1,33 @@
/* udis86 - udis86.h
*
* Copyright (c) 2002-2009 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UDIS86_H
#define UDIS86_H
#include "libudis86/types.h"
#include "libudis86/extern.h"
#include "libudis86/itab.h"
#endif

View File

@ -41,6 +41,17 @@
#ifndef PLATFORM_WINDOWS
#define PLATFORM_WINDOWS 1
#endif
#if defined WIN64 || defined _WIN64
#ifndef PLATFORM_X64
# define PLATFORM_X64 1
#endif
#else
#ifndef PLATFORM_X86
# define PLATFORM_X86 1
#endif
#endif // defined WIN64 || defined _WIN64
#if !defined WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
@ -58,6 +69,7 @@
#define PLATFORM_MAX_PATH MAX_PATH
#define PLATFORM_SEP_CHAR '\\'
#define PLATFORM_SEP_ALTCHAR '/'
#define PLATFORM_SEP "\\"
#define PLATFORM_EXTERN_C extern "C" __declspec(dllexport)
#if defined _MSC_VER && _MSC_VER >= 1400
#define SUBPLATFORM_SECURECRT
@ -73,6 +85,17 @@
#ifndef PLATFORM_POSIX
# define PLATFORM_POSIX 1
#endif
#if defined __x86_64__
#ifndef PLATFORM_X64
# define PLATFORM_X64 1
#endif
#else
#ifndef PLATFORM_X86
# define PLATFORM_X86 1
#endif
#endif // defined __x86_64__
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
@ -84,6 +107,7 @@
#define PLATFORM_MAX_PATH PATH_MAX
#define PLATFORM_SEP_CHAR '/'
#define PLATFORM_SEP_ALTCHAR '\\'
#define PLATFORM_SEP "/"
#define PLATFORM_EXTERN_C extern "C" __attribute__((visibility("default")))
#endif
@ -95,5 +119,25 @@
#define SM_ARRAYSIZE(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#endif
#if defined PLATFORM_X64
#define PLATFORM_ARCH_FOLDER "x64" PLATFORM_SEP
#ifdef PLATFORM_WINDOWS
#define PLATFORM_FOLDER "win64" PLATFORM_SEP
#elif defined PLATFORM_LINUX
#define PLATFORM_FOLDER "linux64" PLATFORM_SEP
#elif defined PLATFORM_APPLE
#define PLATFORM_FOLDER "osx64" PLATFORM_SEP
#endif
#else
#define PLATFORM_ARCH_FOLDER ""
#ifdef PLATFORM_WINDOWS
#define PLATFORM_FOLDER "win32" PLATFORM_SEP
#elif defined PLATFORM_LINUX
#define PLATFORM_FOLDER "linux32" PLATFORM_SEP
#elif defined PLATFORM_APPLE
#define PLATFORM_FOLDER "osx32" PLATFORM_SEP
#endif
#endif // defined PLATFORM_X64
#endif //_INCLUDE_SOURCEMOD_PLATFORM_H_

@ -1 +1 @@
Subproject commit c78349382d97d5a9f20b49975c47d9bb805c125d
Subproject commit a51117e370e679b275ad6c74c31e5b7c81e3508a

View File

@ -38,6 +38,12 @@ folder_list = [
'cfg/sourcemod',
]
if 'x64' in SM.archs:
folder_list.extend([
'addons/sourcemod/bin/x64',
'addons/sourcemod/extensions/x64',
])
# Create the distribution folder hierarchy.
folder_map = {}
for folder in folder_list:
@ -46,11 +52,41 @@ for folder in folder_list:
# Copy binaries.
for cxx_task in SM.binaries:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/bin'])
binpath = cxx_task.binary.path
if '.x64' + os.sep in binpath and not 'sourcemod_mm' in binpath:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/bin/x64'])
else:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/bin'])
for cxx_task in SM.extensions:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions'])
builder.AddCopy(SM.spcomp.binary, folder_map['addons/sourcemod/scripting'])
if '.x64' + os.sep in cxx_task.binary.path:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions/x64'])
else:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions'])
def lipo(binaries, outFolder):
bins = []
binPaths = []
for bin in binaries:
bins.append(bin.binary)
binPaths.append(os.path.join(builder.buildPath, bin.binary.path))
argv = ['lipo', '-create']
binary = os.path.basename(binPaths[0])
outputPath = os.path.join(builder.buildPath, builder.buildFolder, outFolder, binary)
builder.AddCommand(
argv = argv + binPaths + ['-output', outputPath],
inputs = bins,
outputs = [os.path.join(outFolder, binary)],
)
if builder.target.platform == 'mac' and len(SM.archs) > 1:
lipo(SM.spcomp_bins, 'addons/sourcemod/scripting')
else:
for bin_task in SM.spcomp_bins:
if '.x64' + os.sep in bin_task.binary.path:
file = os.path.basename(bin_task.binary.path) + '64'
builder.AddCopy(bin_task.binary, os.path.normpath('addons/sourcemod/scripting/' + file))
else:
builder.AddCopy(bin_task.binary, folder_map['addons/sourcemod/scripting'])
if SM.use_auto_versioning():
# Copy version_auto.inc.
@ -61,7 +97,7 @@ if SM.use_auto_versioning():
# Export PDB files. We write to a file in the build folder which is pretty
# verboten, but it's okay if it's in the root since AMBuild will never try
# to rmdir the root.
full_binary_list = SM.binaries + SM.extensions + [SM.spcomp]
full_binary_list = SM.binaries + SM.extensions + SM.spcomp_bins
with open(os.path.join(builder.buildPath, 'pdblog.txt'), 'w') as fp:
for task in full_binary_list:
fp.write(task.debug.path + '\n')

View File

@ -46,14 +46,22 @@ if ($^O =~ /darwin/) {
push(@conf_argv, '--hl2sdk-root=/Volumes/hgshare');
push(@conf_argv, '--mms-path=/Users/builds/slaves/common/mmsource-1.10');
push(@conf_argv, '--mysql-path=/Users/builds/slaves/common/mysql-5.0');
push(@conf_argv, '--mysql64-path=/Users/builds/slaves/common/mysql-5.0-x86_64');
} elsif ($^O =~ /linux/) {
push(@conf_argv, '--hl2sdk-root=/hgshare');
push(@conf_argv, '--mms-path=/home/builds/common/mmsource-1.10');
push(@conf_argv, '--mysql-path=/home/builds/common/mysql-5.0');
push(@conf_argv, '--mysql64-path=/home/builds/common/mysql-5.0-x86_64');
} elsif ($^O =~ /MSWin/) {
push(@conf_argv, '--hl2sdk-root=H:\\');
}
if ($^O !~ /MSWin/) {
push(@conf_argv, '--target-arch=x86,x64');
} else {
push(@conf_argv, '--target-arch=x86');
}
my $conf_args = join(' ', @conf_argv);
if ($argn > 0 && $^O !~ /MSWin/) {

View File

@ -24,6 +24,25 @@ if [ ! -d "sourcemod" ]; then
fi
fi
getmysql ()
{
if [ ! -d $mysqlfolder ]; then
if [ `command -v wget` ]; then
wget $mysqlurl -O $mysqlfolder.$archive_ext
elif [ `command -v curl` ]; then
curl -o $mysqlfolder.$archive_ext $mysqlurl
else
echo "Failed to locate wget or curl. Install one of these programs to download MySQL."
exit 1
fi
$decomp $mysqlfolder.$archive_ext
mv $mysqlver $mysqlfolder
rm $mysqlfolder.$archive_ext
fi
}
# 32-bit MySQL
mysqlfolder=mysql-5.0
if [ $ismac -eq 1 ]; then
mysqlver=mysql-5.5.28-osx10.5-x86
mysqlurl=https://cdn.mysql.com/archives/mysql-5.5/$mysqlver.$archive_ext
@ -36,20 +55,18 @@ else
mysqlver=mysql-5.6.15-linux-glibc2.5-i686
mysqlurl=https://cdn.mysql.com/archives/mysql-5.6/$mysqlver.$archive_ext
fi
getmysql
if [ ! -d "mysql-5.0" ]; then
if [ `command -v wget` ]; then
wget $mysqlurl -O mysql.$archive_ext
elif [ `command -v curl` ]; then
curl -o mysql.$archive_ext $mysqlurl
else
echo "Failed to locate wget or curl. Install one of these programs to download MySQL."
exit 1
fi
$decomp mysql.$archive_ext
mv $mysqlver mysql-5.0
rm mysql.$archive_ext
# 64-bit MySQL
mysqlfolder=mysql-5.0-x86_64
if [ $ismac -eq 1 ]; then
mysqlver=mysql-5.5.28-osx10.5-x86_64
mysqlurl=https://cdn.mysql.com/archives/mysql-5.5/$mysqlver.$archive_ext
elif [ $iswin -eq 0 ]; then
mysqlver=mysql-5.6.15-linux-glibc2.5-x86_64
mysqlurl=https://cdn.mysql.com/archives/mysql-5.6/$mysqlver.$archive_ext
fi
getmysql
checkout ()
{

View File

@ -1,15 +1,17 @@
# vim: sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
lib = SM.StaticLibrary(builder, 'version')
lib.compiler.includes += [
os.path.join(builder.sourcePath, 'public')
]
lib.compiler.defines.remove('SM_USE_VERSIONLIB')
lib.compiler.sourcedeps += SM.generated_headers
lib.sources += [
'versionlib.cpp'
]
task = builder.Add(lib)
rvalue = {}
for arch in SM.archs:
lib = SM.StaticLibrary(builder, 'version', arch)
lib.compiler.includes += [
os.path.join(builder.sourcePath, 'public')
]
lib.compiler.defines.remove('SM_USE_VERSIONLIB')
lib.compiler.sourcedeps += SM.generated_headers
lib.sources += [
'versionlib.cpp'
]
task = builder.Add(lib)
rvalue = task.binary
rvalue[arch] = task.binary