Skip to content

Commit

Permalink
Repo restructure, PE header parsing, fix Linux DynLibs
Browse files Browse the repository at this point in the history
  • Loading branch information
Scags committed Sep 20, 2023
1 parent 2c1715c commit ca64790
Show file tree
Hide file tree
Showing 23 changed files with 1,230 additions and 549 deletions.
4 changes: 2 additions & 2 deletions AMBuildScript
Expand Up @@ -120,7 +120,7 @@ class ExtensionConfig(object):
'-fPIC',
]

if builder.options.opt == '1':
if builder.options.debug != '1':
cxx.cxxflags += ['-g0']

cxx.linkflags += ['-m32']
Expand Down Expand Up @@ -221,7 +221,7 @@ class ExtensionConfig(object):

def ConfigureForExtension(self, context, compiler):
compiler.cxxincludes += [
os.path.join(context.currentSourcePath),
os.path.join(context.currentSourcePath, 'ext'),
os.path.join(self.sm_root, 'public'),
os.path.join(self.sm_root, 'public', 'extensions'),
os.path.join(self.sm_root, 'sourcepawn', 'include'),
Expand Down
7 changes: 4 additions & 3 deletions AMBuilder
Expand Up @@ -5,9 +5,10 @@ projectName = 'sm-mem'

# smsdk_ext.cpp will be automatically added later
sourceFiles = [
'extension.cpp',
'natives.cpp',
'dynlib.cpp',
'ext/extension.cpp',
'ext/natives.cpp',
'ext/dynlib.cpp',
'ext/rtti.cpp'
]

###############
Expand Down
12 changes: 8 additions & 4 deletions Dockerfile
Expand Up @@ -11,9 +11,9 @@ RUN apt-get update && apt-get install -y \

# Clone SM stuff
WORKDIR /dependencies
RUN git clone -b master https://github.com/alliedmodders/metamod-source.git
RUN git clone -b master https://github.com/alliedmodders/sourcemod.git --recursive
RUN git clone -b master https://github.com/alliedmodders/ambuild.git
RUN git clone -b master https://github.com/alliedmodders/metamod-source.git --depth 1
RUN git clone -b master https://github.com/alliedmodders/sourcemod.git --recursive --depth 1
RUN git clone -b master https://github.com/alliedmodders/ambuild.git --depth 1

WORKDIR /dependencies/ambuild
RUN python3 -m pip install .
Expand All @@ -25,9 +25,13 @@ COPY . .

WORKDIR /project/package

ARG BUILD_MODE=optimize
ENV PY_ARG=--enable-$BUILD_MODE

# Build
RUN python3 ../configure.py \
--mms-path "/dependencies/metamod-source" \
--sm-path "/dependencies/sourcemod" \
--enable-optimize
$PY_ARG

RUN ambuild
4 changes: 4 additions & 0 deletions PackageScript
Expand Up @@ -39,6 +39,7 @@ CopyFiles('pawn', 'addons/sourcemod/scripting/include/smmem',
'sourcemod/scripting/include/smmem/stocks.inc',
'sourcemod/scripting/include/smmem/dynlib.inc',
'sourcemod/scripting/include/smmem/rtti.inc',
'sourcemod/scripting/include/smmem/winnt.inc',
]
)

Expand Down Expand Up @@ -67,3 +68,6 @@ CopyFiles('pawn', 'addons/sourcemod/scripting',
# Copy binaries.
for cxx_task in Extension.extensions:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions'])
# Only copy PDBs in a non-prod environment
if builder.options.debug == '1' and builder.target_platform == 'windows':
builder.AddCopy(cxx_task.debug, folder_map['addons/sourcemod/extensions'])
15 changes: 13 additions & 2 deletions build/build.bat
@@ -1,2 +1,13 @@
py ../configure.py --mms-path "C:/Users/johnm/Documents/GitHub/metamod-source" --sm-path "C:/Users/johnm/Documents/GitHub/sourcemod" --sdks none --enable-optimize
ambuild
@echo off
SET arg=%1

:: Change these if building yourself
SET mms_path="C:/Users/johnm/Documents/GitHub/metamod-source"
SET sm_path="C:/Users/johnm/Documents/GitHub/sourcemod"

:: Allow passing a debug flag for debug builds
SET pyflag=--enable-optimize
IF "%arg%"=="--debug" SET pyflag=--enable-debug

py ../configure.py --mms-path %mms_path% --sm-path %sm_path% --sdks none %pyflag%
ambuild
11 changes: 10 additions & 1 deletion build/build.sh
@@ -1,4 +1,13 @@
#!/usr/bin/env bash

python3 ../configure.py --mms-path "/mnt/c/Users/johnm/Documents/GitHub/metamod-source" --sm-path "/mnt/c/Users/johnm/Documents/GitHub/sourcemod" --enable-optimize
# Change these if building yourself
mms_path="/mnt/c/Users/johnm/Documents/GitHub/metamod-source"
sm_path="/mnt/c/Users/johnm/Documents/GitHub/sourcemod"

py_arg="--enable-optimize"
if [ "$1" == "--debug" ]; then
py_arg="--enable-debug"
fi

python3 ../configure.py --mms-path $mms_path --sm-path $sm_path $py_arg
ambuild
9 changes: 7 additions & 2 deletions build/build_docker.sh
@@ -1,7 +1,12 @@
#!/usr/bin/env bash

docker build -f ../Dockerfile -t sm-mem ../
dockerflag=""
if [ "$1" == "--debug" ]; then
dockerflag="--build-arg BUILD_MODE=debug"
fi

docker build $dockerflag -f ../Dockerfile -t sm-mem ../
container_id=$(docker create sm-mem)
docker cp "${container_id}:/project/package/package" .
docker rm ${container_id}
docker image prune -f
docker image prune -f
54 changes: 0 additions & 54 deletions dynlib.cpp

This file was deleted.

113 changes: 113 additions & 0 deletions ext/dynlib.cpp
@@ -0,0 +1,113 @@
#include "extension.h"
#include "dynlib.h"

#ifdef PLATFORM_WINDOWS
#include <Windows.h>
#endif

#include <sstream>
#include <fstream>

// https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c
static bool endswith(const std::string &str, const char *suffix, unsigned suffixLen)
{
return str.size() >= suffixLen && str.compare(str.size() - suffixLen, suffixLen, suffix, suffixLen) == 0;
}

DynLib::DynLib(const std::string &name)
: m_Name(name)
{
#ifdef PLATFORM_WINDOWS
m_Handle = LoadLibraryA(m_Name.c_str());
if (m_Handle == nullptr)
{
// Try and fix up the name
if (!endswith(m_Name, ".dll", 4))
{
m_Name += ".dll";
m_Handle = LoadLibraryA(m_Name.c_str());
}
}

m_BaseAddress = (void *)m_Handle;
#elif defined PLATFORM_POSIX
m_Handle = dlopen(m_Name.c_str(), RTLD_LAZY);
if (m_Handle == nullptr)
{
// Try and fix up the name
if (!endswith(m_Name, ".so", 3))
{
m_Name += ".so";
m_Handle = dlopen(m_Name.c_str(), RTLD_LAZY);
}
}

if (m_Handle != nullptr)
{
m_BaseAddress = LoadBaseAddress(m_Name);
// Name is not full path
if (m_BaseAddress == nullptr)
{
char abspath[260];
char *rpath = realpath(m_Name.c_str(), abspath);
if (rpath != nullptr)
{
m_Name = rpath;
m_BaseAddress = LoadBaseAddress(m_Name);
}
}
}
#endif
}

DynLib::~DynLib()
{
if (m_Handle != nullptr)
{
#ifdef PLATFORM_WINDOWS
FreeLibrary(m_Handle);
#elif defined PLATFORM_POSIX
dlclose(m_Handle);
#endif
}
}

void *DynLib::ResolveSymbol(const char *sym)
{
return memutils->ResolveSymbol((void *)m_Handle, sym);
}

void *DynLib::FindPattern(const char *pattern, size_t len)
{
return memutils->FindPattern(m_BaseAddress, pattern, len);
}

std::string DynLib::ErrorMessage()
{
#ifdef PLATFORM_WINDOWS
std::stringstream ss;
ss << std::hex << GetLastError();
return "0x" + ss.str();
#elif defined PLATFORM_POSIX
const char *err = dlerror();
return err ? err : "";
#endif
}

void *DynLib::LoadBaseAddress(const std::string &name)
{
std::ifstream maps("/proc/self/maps");
std::string line;
void *startAddr = nullptr;
while (std::getline(maps, line))
{
if (line.find(name) != std::string::npos)
{
std::stringstream ss(line);
char dash;
ss >> std::hex >> startAddr >> dash;
break;
}
}
return startAddr;
}
30 changes: 10 additions & 20 deletions dynlib.h → ext/dynlib.h
@@ -1,5 +1,4 @@
#ifndef DYNLIB
#define DYNLIB
#pragma once

#include "sm_platform.h"
#include <string>
Expand All @@ -13,35 +12,26 @@
class DynLib
{
private:
std::string m_Name;
std::string m_Name = "";
#ifdef PLATFORM_WINDOWS
HMODULE m_Handle;
void *m_BaseAddress;
HMODULE m_Handle = {};
#elif defined PLATFORM_POSIX
void *m_Handle;
Dl_info m_Info;
void *m_Handle = {};
#endif
void *m_BaseAddress = {};

static void *LoadBaseAddress(const std::string &name);

public:
DynLib(const std::string &name);
~DynLib();
void *ResolveSymbol(const char *sym);
void *FindPattern(const char *pattern, size_t len);
void *GetExport(const char *name);

std::string &GetName() { return m_Name; }
void *GetBaseAddress()
{
#ifdef PLATFORM_WINDOWS
return m_BaseAddress;
#elif defined PLATFORM_POSIX
return m_Info.dli_fbase;
#endif
}
void *GetBaseAddress() { return m_BaseAddress; }

#ifdef PLATFORM_POSIX
Dl_info *GetDlInfo() { return &m_Info; }
#endif
bool IsLoaded() { return GetBaseAddress() != nullptr; }

static std::string ErrorMessage();
};
#endif // DYNLIB
File renamed without changes.
7 changes: 1 addition & 6 deletions extension.h → ext/extension.h
Expand Up @@ -29,8 +29,7 @@
* Version: $Id$
*/

#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#pragma once

#include "smsdk_ext.h"

Expand Down Expand Up @@ -106,7 +105,3 @@ class SMMem : public SDKExtension, public IHandleTypeDispatch
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlen);
#endif
};

extern sp_nativeinfo_t g_Natives[];

#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_

0 comments on commit ca64790

Please sign in to comment.