├── .gitignore ├── build ├── icon.ico ├── makefile ├── pefrmdllembed.cbp ├── pefrmdllembed.sln ├── pefrmdllembed.vcxproj ├── pefrmdllembed.workspace ├── resource.h └── verinfo.rc ├── input.dll ├── input.exe ├── input_x64.dll ├── input_x64.exe ├── readme.md ├── release_stuff ├── SA_CreateCar.asi ├── VC_PedPainting.asi └── readme.txt ├── src ├── main.cpp ├── option.cpp └── option.h └── vendor ├── asmjit ├── BREAKING.md ├── LICENSE.md ├── README.md ├── build │ ├── asmjit.cbp │ ├── asmjit.sln │ ├── asmjit.vcxproj │ ├── asmjit.vcxproj.filters │ └── makefile ├── cxxconfig.js ├── src │ └── asmjit │ │ ├── arm.h │ │ ├── asmjit.h │ │ ├── asmjit_apibegin.h │ │ ├── asmjit_apiend.h │ │ ├── asmjit_build.h │ │ ├── base.h │ │ ├── base │ │ ├── arch.cpp │ │ ├── arch.h │ │ ├── assembler.cpp │ │ ├── assembler.h │ │ ├── codebuilder.cpp │ │ ├── codebuilder.h │ │ ├── codecompiler.cpp │ │ ├── codecompiler.h │ │ ├── codeemitter.cpp │ │ ├── codeemitter.h │ │ ├── codeholder.cpp │ │ ├── codeholder.h │ │ ├── constpool.cpp │ │ ├── constpool.h │ │ ├── cpuinfo.cpp │ │ ├── cpuinfo.h │ │ ├── func.cpp │ │ ├── func.h │ │ ├── globals.cpp │ │ ├── globals.h │ │ ├── inst.cpp │ │ ├── inst.h │ │ ├── logging.cpp │ │ ├── logging.h │ │ ├── misc_p.h │ │ ├── operand.cpp │ │ ├── operand.h │ │ ├── osutils.cpp │ │ ├── osutils.h │ │ ├── regalloc.cpp │ │ ├── regalloc_p.h │ │ ├── runtime.cpp │ │ ├── runtime.h │ │ ├── simdtypes.h │ │ ├── string.cpp │ │ ├── string.h │ │ ├── utils.cpp │ │ ├── utils.h │ │ ├── vmem.cpp │ │ ├── vmem.h │ │ ├── zone.cpp │ │ └── zone.h │ │ └── x86.h └── test │ ├── asmjit.h │ ├── asmjit_bench_x86.cpp │ ├── asmjit_test_misc.h │ ├── asmjit_test_opcode.cpp │ ├── asmjit_test_opcode.h │ ├── asmjit_test_unit.cpp │ ├── asmjit_test_x86_asm.cpp │ ├── asmjit_test_x86_cc.cpp │ ├── broken.cpp │ └── broken.h ├── asmjitshared ├── build │ ├── asmjitshared.cbp │ ├── asmjitshared.sln │ ├── asmjitshared.vcxproj │ ├── asmjitshared.vcxproj.filters │ └── makefile ├── include │ └── asmjitshared.h └── src │ └── Relocation.cpp ├── eirrepo ├── LICENSE └── sdk │ ├── ABIHelpers.h │ ├── AVLTree.h │ ├── AVLTree.helpers.h │ ├── DataUtil.h │ ├── DynamicTypeSystem.h │ ├── DynamicTypeSystem.natvis │ ├── Endian.h │ ├── Endian.natvis │ ├── Function.h │ ├── GlobPattern.h │ ├── MacroUtils.h │ ├── Map.h │ ├── MathSlice.algorithms.h │ ├── MathSlice.h │ ├── MemoryRaw.h │ ├── MemoryUtils.h │ ├── MemoryUtils.legacy.h │ ├── MemoryUtils.natvis │ ├── MemoryUtils.stream.h │ ├── MetaHelpers.h │ ├── MultiString.h │ ├── MultiString.natvis │ ├── NumericFormat.h │ ├── OSUtils.arrvmem.h │ ├── OSUtils.h │ ├── OSUtils.memheap.h │ ├── OSUtils.vecvmem.h │ ├── OSUtils.vmem.h │ ├── OSUtils.vmemconf.h │ ├── PluginFactory.h │ ├── PluginFlavors.h │ ├── PluginHelpers.h │ ├── RingBuffer.h │ ├── Set.h │ ├── SortedSliceSector.h │ ├── String.h │ ├── String.natvis │ ├── StringUtils.h │ ├── UniChar.casesense.h │ ├── UniChar.h │ ├── UniChar.strmodel.h │ ├── Vector.h │ ├── Vector.natvis │ ├── avlsetmaputil.h │ ├── eirutils.h │ └── rwlist.hpp └── peframework ├── build ├── makefile ├── peframework.cbp ├── peframework.sln ├── peframework.vcxproj └── peloader.natvis ├── include ├── peexcept.h ├── peframework.h ├── peloader.common.h ├── peloader.freg.arm.legacy.h ├── peloader.freg.arm32.h ├── peloader.freg.arm64.h ├── peloader.freg.h ├── peloader.freg.mips32.h ├── peloader.freg.x64.h ├── peloader.h ├── peloader.serialize.h └── pestream.h ├── readme.md └── src ├── peloader.basereloc.cpp ├── peloader.cpp ├── peloader.datadirs.cpp ├── peloader.datadirs.hxx ├── peloader.debug.cpp ├── peloader.exports.cpp ├── peloader.freg.cpp ├── peloader.imports.cpp ├── peloader.internal.hxx ├── peloader.memory.cpp ├── peloader.read.cpp ├── peloader.resource.cpp └── peloader.write.cpp /build/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/build/icon.ico -------------------------------------------------------------------------------- /build/makefile: -------------------------------------------------------------------------------- 1 | CC := g++ 2 | CCFLAGS := -std=c++17 3 | srcdir := $(CURDIR)/../src 4 | objdir := $(CURDIR)/../obj/linux 5 | sources := $(shell find $(srcdir) -name "*.cpp") 6 | headers := $(shell find $(srcdir) -name "*.h") $(shell find $(srcdir) -name "*.hxx") 7 | objects := $(patsubst $(srcdir)/%,$(objdir)/%.o,$(sources)) 8 | INCLUDE := \ 9 | -I$(CURDIR)/../vendor/peframework/include \ 10 | -I$(CURDIR)/../vendor/eirrepo \ 11 | -I$(CURDIR)/../vendor/asmjit/src \ 12 | -I$(CURDIR)/../vendor/asmjitshared/include 13 | LIBDIRS := \ 14 | -L$(CURDIR)/../vendor/peframework/lib/linux \ 15 | -L$(CURDIR)/../vendor/asmjit/lib/linux \ 16 | -L$(CURDIR)/../vendor/asmjitshared/lib/linux 17 | BUILD_DIR := \ 18 | $(CURDIR) 19 | 20 | main : $(objects) $(headers) peframework.vendor asmjit.vendor asmjitshared.vendor ; \ 21 | cd $(BUILD_DIR) ; \ 22 | $(CC) $(CCFLAGS) $(LIBDIRS) -o ../bin/pefrmdllembed $(objects) -l peframework -l asmjit -l asmjitshared 23 | 24 | $(objdir)/%.o : $(srcdir)/% ; \ 25 | mkdir -p $(dir $@) ; \ 26 | $(CC) $(CCFLAGS) -O3 -o $@ -c $< -Wno-invalid-offsetof $(INCLUDE) ; 27 | 28 | %.vendor : ; \ 29 | cd $(BUILD_DIR)/../vendor/$(patsubst %.vendor,%,$@)/build/ ; \ 30 | make 31 | 32 | clean : peframework.vclean asmjit.vclean asmjitshared.vclean ; \ 33 | rm -rf $(objdir) 34 | 35 | %.vclean : ; \ 36 | cd $(BUILD_DIR)/../vendor/$(patsubst %.vclean,%,$@)/build/ ; \ 37 | make clean 38 | 39 | print-%: ; @echo '$*=$($*)' -------------------------------------------------------------------------------- /build/pefrmdllembed.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 56 | 57 | -------------------------------------------------------------------------------- /build/pefrmdllembed.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29519.87 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pefrmdllembed", "pefrmdllembed.vcxproj", "{316C1760-4495-44CD-8AD7-80D0EFE856E7}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {B87D15CC-5429-47F3-A065-94359A3A6719} = {B87D15CC-5429-47F3-A065-94359A3A6719} 9 | {7BA054CF-1A77-437D-8659-F2223380B2D5} = {7BA054CF-1A77-437D-8659-F2223380B2D5} 10 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05} = {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05} 11 | EndProjectSection 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peframework", "..\vendor\peframework\build\peframework.vcxproj", "{D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}" 14 | EndProject 15 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "..\vendor\asmjit\build\asmjit.vcxproj", "{B87D15CC-5429-47F3-A065-94359A3A6719}" 16 | EndProject 17 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjitshared", "..\vendor\asmjitshared\build\asmjitshared.vcxproj", "{7BA054CF-1A77-437D-8659-F2223380B2D5}" 18 | EndProject 19 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D55E2194-7B0F-4C0E-98DD-6D7D061E7E85}" 20 | EndProject 21 | Global 22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 23 | Debug|x64 = Debug|x64 24 | Debug|x86 = Debug|x86 25 | Release|x64 = Release|x64 26 | Release|x86 = Release|x86 27 | EndGlobalSection 28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 29 | {316C1760-4495-44CD-8AD7-80D0EFE856E7}.Debug|x64.ActiveCfg = Debug|x64 30 | {316C1760-4495-44CD-8AD7-80D0EFE856E7}.Debug|x64.Build.0 = Debug|x64 31 | {316C1760-4495-44CD-8AD7-80D0EFE856E7}.Debug|x86.ActiveCfg = Debug|Win32 32 | {316C1760-4495-44CD-8AD7-80D0EFE856E7}.Debug|x86.Build.0 = Debug|Win32 33 | {316C1760-4495-44CD-8AD7-80D0EFE856E7}.Release|x64.ActiveCfg = Release|x64 34 | {316C1760-4495-44CD-8AD7-80D0EFE856E7}.Release|x64.Build.0 = Release|x64 35 | {316C1760-4495-44CD-8AD7-80D0EFE856E7}.Release|x86.ActiveCfg = Release|Win32 36 | {316C1760-4495-44CD-8AD7-80D0EFE856E7}.Release|x86.Build.0 = Release|Win32 37 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Debug|x64.ActiveCfg = Debug|x64 38 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Debug|x64.Build.0 = Debug|x64 39 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Debug|x86.ActiveCfg = Debug|Win32 40 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Debug|x86.Build.0 = Debug|Win32 41 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Release|x64.ActiveCfg = Release|x64 42 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Release|x64.Build.0 = Release|x64 43 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Release|x86.ActiveCfg = Release|Win32 44 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Release|x86.Build.0 = Release|Win32 45 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Debug|x64.ActiveCfg = Debug|x64 46 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Debug|x64.Build.0 = Debug|x64 47 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Debug|x86.ActiveCfg = Debug|Win32 48 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Debug|x86.Build.0 = Debug|Win32 49 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Release|x64.ActiveCfg = Release|x64 50 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Release|x64.Build.0 = Release|x64 51 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Release|x86.ActiveCfg = Release|Win32 52 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Release|x86.Build.0 = Release|Win32 53 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Debug|x64.ActiveCfg = Debug|x64 54 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Debug|x64.Build.0 = Debug|x64 55 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Debug|x86.ActiveCfg = Debug|Win32 56 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Debug|x86.Build.0 = Debug|Win32 57 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Release|x64.ActiveCfg = Release|x64 58 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Release|x64.Build.0 = Release|x64 59 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Release|x86.ActiveCfg = Release|Win32 60 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Release|x86.Build.0 = Release|Win32 61 | EndGlobalSection 62 | GlobalSection(SolutionProperties) = preSolution 63 | HideSolutionNode = FALSE 64 | EndGlobalSection 65 | GlobalSection(ExtensibilityGlobals) = postSolution 66 | SolutionGuid = {A827C3BA-E3EA-4AB5-AA71-9DCD784B62D1} 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /build/pefrmdllembed.workspace: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /build/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by verinfo.rc 4 | // 5 | #define IDI_ICON3 103 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 104 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /build/verinfo.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/build/verinfo.rc -------------------------------------------------------------------------------- /input.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/input.dll -------------------------------------------------------------------------------- /input.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/input.exe -------------------------------------------------------------------------------- /input_x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/input_x64.dll -------------------------------------------------------------------------------- /input_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/input_x64.exe -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # What is this? 2 | This tool will embed dll files or asi files into exe. 3 | In some cases, asi/dll version info might be overriden, overwrited, and Resource Hacker might be unable to edit, or even load the final exe 4 | 5 | This project is based on http://pefrm-units.osdn.jp/pefrmdllembed.html 6 | 7 | # Requiements (no need, already included) 8 | eirrepo https://svn.osdn.net/svnroot/eirrepo/common 9 | peframework https://svn.osdn.net/svnroot/peframework/library 10 | asmjit https://svn.osdn.net/svnroot/eirasmjit/eirasmjit / https://github.com/asmjit/asmjit 11 | asmjitshared https://svn.osdn.net/svnroot/eirasmjit/shared 12 | 13 | https://osdn.net/users/quiret/ 14 | 15 | # Compile 16 | Open build/pefrmdllembed.sln with Visual Studio 2017+ 17 | 18 | # HOW TO USE 19 | 1) unpack pefrmdllembed.exe into a new folder on Desktop 20 | 2) copy your exe into the folder 21 | 3) copy your asi file into the folder 22 | 4) run cmd.exe in the new folder on Desktop 23 | 5) type into commandline: pefrmdllembed *exe filename* *asi filename* output.exe 24 | where you replace things with the proper filenames 25 | 6) Use output.exe, asi and original exe might not be needed now. 26 | 27 | You can inject multiple ASI files by giving more ASI filenames (but you must give output exe filename). 28 | 29 | `dll2exe base202012-swine.exe SWINE.nutmaster.asi releasepigz.exe` 30 | 31 | # COMMANDLINE OPTIONS 32 | 33 | ``` 34 | -efix: restores the original executable entry point after embedding so that version detection of .ASI files 35 | can use it. fixes support for OLA and modloader (possibly many more). 36 | -impinj: removes DLL import dependencies by injecting the exports of the ASI directly into the import table; the ASI/DLL has 37 | to have the same name as the DLL import module 38 | -noexp: skips embedding DLL exports into the output executable 39 | -help: displays usage description 40 | ``` -------------------------------------------------------------------------------- /release_stuff/SA_CreateCar.asi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/release_stuff/SA_CreateCar.asi -------------------------------------------------------------------------------- /release_stuff/VC_PedPainting.asi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/release_stuff/VC_PedPainting.asi -------------------------------------------------------------------------------- /release_stuff/readme.txt: -------------------------------------------------------------------------------- 1 | GTA ASI Injector, build date June 06th 2019, by The_GTA 2 | pefrmdllembed - http://pefrm-units.osdn.jp/pefrmdllembed.html 3 | =========================================================== 4 | 5 | This tool is made to install ASI files directly into GTA executables. It works just like any ASI loader but 6 | puts the ASI into the EXE directly, avoiding having to ship multiple ASI files. 7 | 8 | You can test things with two sample ASIs. They are from DK22Pac's plugin-sdk. 9 | Find plugin-sdk here: https://github.com/DK22Pac/plugin-sdk 10 | - SA_CreateCar (compatible with SA 1.0 US): press tab to spawn funny Infernus 11 | - VC_PedPainting (compatible with VC 1.0 US): Tommy is painted red ingame 12 | 13 | Virus scan report: 14 | win32: https://www.virustotal.com/gui/file/b05784aaec66b9eb82111ce345c68e47d39d3c1004755ec8838b08891508b632/detection 15 | 16 | ========================== 17 | HOW TO USE 18 | ========================== 19 | 1) unpack pefrmdllembed.exe into a new folder on Desktop 20 | 2) copy your gta exe into the folder 21 | 3) copy your asi file into the folder 22 | 4) run cmd.exe in the new folder on Desktop 23 | 5) type into commandline: pefrmdllembed *gta exe filename* *asi filename* output.exe 24 | where you replace things with the proper filenames 25 | 6) copy output.exe into your GTA folder 26 | 7) remove the .asi from your GTA folder if present; not required anymore 27 | 8) run output.exe 28 | 29 | You can inject multiple ASI files by giving more ASI filenames (but you must give output exe filename). 30 | 31 | ========================== 32 | COMMANDLINE OPTIONS 33 | ========================== 34 | 35 | -efix: restores the original executable entry point after embedding so that version detection of .ASI files 36 | can use it. fixes support for OLA and modloader (possibly many more). 37 | -impinj: removes DLL import dependencies by injecting the exports of the ASI directly into the import table; the ASI/DLL has 38 | to have the same name as the DLL import module 39 | -noexp: skips embedding DLL exports into the output executable 40 | -help: displays usage description 41 | 42 | =========================== 43 | KNOWN WORKING 44 | =========================== 45 | SilentPatch, outfit.asi, SkyGFX, CLEO, OLA, modloader and many more! Make many custom EXE files! 46 | 47 | 48 | Hope this tool is useful to you. 49 | 50 | - Martin -------------------------------------------------------------------------------- /src/option.cpp: -------------------------------------------------------------------------------- 1 | #include "option.h" 2 | 3 | OptionParser::OptionParser( const char *args[], size_t numArgs ) 4 | { 5 | this->args = args; 6 | this->numArgs = numArgs; 7 | 8 | this->curArg = 0; 9 | 10 | this->curArgPtr = UpdateArgPtr( 0, numArgs ); 11 | } 12 | 13 | OptionParser::~OptionParser( void ) 14 | { 15 | return; 16 | } 17 | 18 | static const char OPTION_INITIALIZER = '-'; 19 | 20 | std::string OptionParser::FetchOption( void ) 21 | { 22 | size_t argIdx = this->curArg; 23 | size_t numArgs = this->numArgs; 24 | 25 | bool isParsingOption = false; 26 | std::string optString; 27 | 28 | const char *argPtr = this->curArgPtr; 29 | 30 | if ( argIdx < numArgs ) 31 | { 32 | while ( true ) 33 | { 34 | // Check if we can fetch from the current argument. 35 | char c = *argPtr; 36 | 37 | bool advanceIndex = false; 38 | 39 | if ( c == 0 ) 40 | { 41 | // Need to advance to next argument. 42 | advanceIndex = true; 43 | } 44 | else 45 | { 46 | argPtr++; 47 | 48 | if ( c == OPTION_INITIALIZER ) 49 | { 50 | isParsingOption = true; 51 | } 52 | else if ( isParsingOption ) 53 | { 54 | if ( c == ' ' || c == '\t' ) 55 | { 56 | // Terminate the option parsing. 57 | advanceIndex = true; 58 | } 59 | else 60 | { 61 | optString += c; 62 | } 63 | } 64 | else 65 | { 66 | // Failure. No options. 67 | argPtr--; 68 | break; 69 | } 70 | } 71 | 72 | if ( advanceIndex ) 73 | { 74 | argIdx++; 75 | argPtr = UpdateArgPtr( argIdx, numArgs ); 76 | 77 | if ( isParsingOption || argIdx >= numArgs ) 78 | { 79 | break; 80 | } 81 | } 82 | } 83 | } 84 | 85 | this->curArg = argIdx; 86 | this->curArgPtr = argPtr; 87 | 88 | return optString; 89 | } -------------------------------------------------------------------------------- /src/option.h: -------------------------------------------------------------------------------- 1 | #ifndef _OPTION_UTILITIES_ 2 | #define _OPTION_UTILITIES_ 3 | 4 | #include 5 | 6 | struct OptionParser 7 | { 8 | OptionParser( const char *args[], size_t numArgs ); 9 | ~OptionParser( void ); 10 | 11 | std::string FetchOption( void ); 12 | 13 | inline size_t GetArgIndex( void ) const { return this->curArg; } 14 | inline const char* GetArgPointer( void ) const { return this->curArgPtr; } 15 | 16 | private: 17 | inline const char* UpdateArgPtr( size_t argIdx, size_t numArgs ) 18 | { 19 | if ( argIdx < numArgs ) 20 | { 21 | return this->args[ argIdx ]; 22 | } 23 | else 24 | { 25 | return nullptr; 26 | } 27 | } 28 | 29 | // Management variables. 30 | const char **args; 31 | size_t numArgs; 32 | 33 | // Current iteration status. 34 | size_t curArg; 35 | const char *curArgPtr; 36 | }; 37 | 38 | #endif //_OPTION_UTILITIES_ -------------------------------------------------------------------------------- /vendor/asmjit/BREAKING.md: -------------------------------------------------------------------------------- 1 | 2016-07-20 2 | ---------- 3 | 4 | * Global `asmjit_cast<>` removed and introduced a more type-safe `asmjit::ptr_cast<>`, which can cast a function to `void*` (and vice-versa), but will refuse to cast a function to `void**`, for example. Just change `asmjit_cast` to `asmjit::ptr_cast` and everything should work as usual. As a consequence, the Runtime now contains a typesafe (templated) `add()` and `remove()` methods that accept a function type directly, no need to cast manually to `void*` and `void**`. If you use your own runtime rename your virtual methods from `add` to `_add` and from `release` to `_release` and enjoy the type-safe wrappers. 5 | * Removed `Logger::Style` and `uint32_t style` parameter in Logging API. It was never used for anything so it was removed. 6 | * There is a new `CodeEmitter` base class that defines assembler building blocks that are implemented by `Assembler` and `CodeBuilder`. `CodeCompiler` is now based on `CodeBuilder` and shares its instruction storage functionality. Most API haven't changed, just base classes and new functionality has been added. It's now possible to serialize code for further processing by using `CodeBuilder`. 7 | * Renamed compile-time macro `ASMJIT_DISABLE_LOGGER` to `ASMJIT_DISABLE_LOGGING`. There is a new `Formatter` class which is also disabled with this option. 8 | 9 | * Operand API is mostly intact, omitting Var/Reg should fix most compile-time errors. There is now no difference between a register index and register id internally. If you ever used `reg.getRegIndex()` then use `reg.getId()` instead. Also renamed `isInitialized()` to `isValid()`. 10 | * There are much more changes, but they are mostly internal and keeping most operand methods compatible. 11 | * Added new functionality into `asmjit::x86` namespace related to operands. 12 | * X86Xmm/X86Ymm/X86Zmm register operands now inherit from X86Vec. 13 | * Register kind (was register class) is now part of `Reg` operand, you can get it by using `reg.getRegKind()`. 14 | * Register class enum moved to `X86Reg`, `kX86RegClassGp` is now `X86Reg::kKindGp`. 15 | * Register type enum moved to `X86Reg`, `kX86RegTypeXmm` is now `X86Reg::kRegXmm`. 16 | * Register index enum moved to `X86Gp`, `kX86RegIndexAx` is now `X86Gp::kIdAx`. 17 | * Segment index enum moved to `X86Seg`, `kX86SegFs` is now `X86Seg::kIdFs`. 18 | * If you used `asmjit::noOperand` for any reason, change it to `Operand()`. 19 | 20 | * CodeBuilder and CodeCompiler now contain different prefix of their nodes to distinguish between them: 21 | 22 | * Rename `HLNode` to `CBNode` (CodeBuilder node). 23 | * Rename all other `HL` to `CB`. 24 | * Rename `X86FuncNode` to `CCFunc` (CodeCompiler function), no more arch specific prefixes here. 25 | * Rename `X86CallNode` to `CCFuncCall` (CodeCompiler function-call), also, no more X86 prefix. 26 | 27 | * AsmJit now uses CodeHolder to hold code. You don't need `Runtime` anymore if you don't plan to execute the code or if you plan to relocate it yourself: 28 | 29 | ```c++ 30 | CodeHolder code; // Create CodeHolder (holds the code). 31 | code.init(CodeInfo(ArchInfo::kIdX64)); // Initialize CodeHolder to hold X64 code. 32 | 33 | // Everything else as usual: 34 | X86Assembler a(&code); // Create the emitter (Assembler, CodeBuilder, CodeCompiler). 35 | ``` 36 | 37 | * Initializing with JitRuntime involves using CodeHolder: 38 | 39 | ```c++ 40 | JitRuntime rt; // Create JitRuntime. 41 | 42 | CodeHolder code; // Create CodeHolder. 43 | code.init(rt.getCodeInfo()); // Initialize CodeHolder to match the JitRuntime. 44 | 45 | X86Assembler a(&code); // Create the emitter (Assembler, CodeBuilder, CodeCompiler). 46 | ... // Generate some code. 47 | 48 | typedef void (*SomeFunc)(void); // Prototype of the function you generated. 49 | 50 | SomeFunc func; // Function pointer. 51 | Error err = rt.add(&func, &code); // Add the generated function to the runtime. 52 | 53 | rt.remove(func); // Remove the generated function from the runtime. 54 | ``` 55 | 56 | * Merged virtual registers (known as variables or Vars) into registers themselves, making the interface simpler: 57 | 58 | ```c++ 59 | X86GpReg/X86GpVar merged to X86Gp 60 | X86MmReg/X86MmVar merged to X86Mm 61 | X86XmmReg/X86XmmVar merged to X86Xmm 62 | X86YmmReg/X86YmmVar merged to X86Ymm 63 | ``` 64 | 65 | * Refactored instruction database, moved many enums related to instructions into `X86Inst`. Also some instructions were wrong (having wrong signature in Assembler and Compiler) and were fixed. 66 | 67 | ```c++ 68 | X86InstInfo renamed to X86Inst 69 | kX86InstIdSomething renamed to X86Inst::kIdSomething 70 | kX86InstOptionSomething renamed to X86Inst::kOptionSomething 71 | kX86CondSomething renamed to X86Inst::kCondSomething 72 | kX86CmpSomething renamed to X86Inst::kCmpSomething 73 | kX86VCmpSomething renamed to X86Inst::kVCmpSomething 74 | kX86PrefetchSomething renamed to X86Inst::kPrefetchSomething 75 | ``` 76 | -------------------------------------------------------------------------------- /vendor/asmjit/LICENSE.md: -------------------------------------------------------------------------------- 1 | AsmJit - Complete x86/x64 JIT and Remote Assembler for C++ 2 | Copyright (c) 2008-2016, Petr Kobalicek 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | -------------------------------------------------------------------------------- /vendor/asmjit/build/asmjit.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 45 | 46 | -------------------------------------------------------------------------------- /vendor/asmjit/build/asmjit.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjit.vcxproj", "{B87D15CC-5429-47F3-A065-94359A3A6719}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Debug|x64.ActiveCfg = Debug|x64 17 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Debug|x64.Build.0 = Debug|x64 18 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Debug|x86.ActiveCfg = Debug|Win32 19 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Debug|x86.Build.0 = Debug|Win32 20 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Release|x64.ActiveCfg = Release|x64 21 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Release|x64.Build.0 = Release|x64 22 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Release|x86.ActiveCfg = Release|Win32 23 | {B87D15CC-5429-47F3-A065-94359A3A6719}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /vendor/asmjit/build/makefile: -------------------------------------------------------------------------------- 1 | CC := g++ 2 | CCFLAGS := -std=c++17 3 | srcdir := $(CURDIR)/../src/asmjit 4 | objdir := $(CURDIR)/../obj/linux 5 | sources := $(shell find $(srcdir) -name "*.cpp") 6 | headers := $(shell find $(srcdir) -name "*.h") $(shell find $(srcdir) -name "*.hxx") 7 | objects := $(patsubst $(srcdir)/%,$(objdir)/%.o,$(sources)) 8 | LIBMAKE = ar 9 | INCLUDE := 10 | 11 | main : $(objects) $(headers) ; mkdir -p ../lib/linux/ ; \ 12 | $(LIBMAKE) rcs ../lib/linux/libasmjit.a $(objects) 13 | 14 | $(objdir)/%.o : $(srcdir)/% ; \ 15 | mkdir -p $(dir $@) ; \ 16 | $(CC) $(CCFLAGS) -O3 -o $@ -c $< $(INCLUDE) ; 17 | 18 | clean : ; \ 19 | rm -rf $(objdir) 20 | 21 | print-%: ; @echo '$*=$($*)' -------------------------------------------------------------------------------- /vendor/asmjit/cxxconfig.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | product: "asmjit", 3 | version: "1.0.0", 4 | 5 | prefix: "ASMJIT", 6 | source: "src/asmjit", 7 | 8 | tools: { 9 | NoTabs : true, 10 | NoTrailingLines : true, 11 | NoTrailingSpaces: true, 12 | UnixEOL : true, 13 | SortIncludes : true, 14 | ExpandTemplates : true 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/arm.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_ARM_H 9 | #define _ASMJIT_ARM_H 10 | 11 | // [Dependencies] 12 | #include "./base.h" 13 | 14 | #include "./arm/armassembler.h" 15 | #include "./arm/armbuilder.h" 16 | #include "./arm/armcompiler.h" 17 | #include "./arm/arminst.h" 18 | #include "./arm/armoperand.h" 19 | 20 | // [Guard] 21 | #endif // _ASMJIT_ARM_H 22 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/asmjit.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_ASMJIT_H 9 | #define _ASMJIT_ASMJIT_H 10 | 11 | // ============================================================================ 12 | // [asmjit_mainpage] 13 | // ============================================================================ 14 | 15 | //! \mainpage 16 | //! 17 | //! AsmJit - Complete x86/x64 JIT and Remote Assembler for C++. 18 | //! 19 | //! Introduction provided by the project page at https://github.com/asmjit/asmjit. 20 | 21 | //! \defgroup asmjit_base AsmJit Base API (architecture independent) 22 | //! 23 | //! \brief Backend Neutral API. 24 | 25 | //! \defgroup asmjit_x86 AsmJit X86/X64 API 26 | //! 27 | //! \brief X86/X64 Backend API. 28 | 29 | //! \defgroup asmjit_arm AsmJit ARM32/ARM64 API 30 | //! 31 | //! \brief ARM32/ARM64 Backend API. 32 | 33 | // [Dependencies] 34 | #include "./base.h" 35 | 36 | // [X86/X64] 37 | #if defined(ASMJIT_BUILD_X86) 38 | #include "./x86.h" 39 | #endif // ASMJIT_BUILD_X86 40 | 41 | // [ARM32/ARM64] 42 | #if defined(ASMJIT_BUILD_ARM) 43 | #include "./arm.h" 44 | #endif // ASMJIT_BUILD_ARM 45 | 46 | // [Guard] 47 | #endif // _ASMJIT_ASMJIT_H 48 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/asmjit_apibegin.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Dependencies] 8 | #if !defined(_ASMJIT_BUILD_H) 9 | # include "./build.h" 10 | #endif // !_ASMJIT_BUILD_H 11 | 12 | // [Guard] 13 | #if !defined(ASMJIT_API_SCOPE) 14 | # define ASMJIT_API_SCOPE 15 | #else 16 | # error "[asmjit] api-scope is already active, previous scope not closed by asmjit_apiend.h?" 17 | #endif // ASMJIT_API_SCOPE 18 | 19 | // ============================================================================ 20 | // [C++ Support] 21 | // ============================================================================ 22 | 23 | // [NoExcept] 24 | #if !ASMJIT_CC_HAS_NOEXCEPT && !defined(noexcept) 25 | # define noexcept ASMJIT_NOEXCEPT 26 | # define ASMJIT_UNDEF_NOEXCEPT 27 | #endif // !ASMJIT_CC_HAS_NOEXCEPT && !noexcept 28 | 29 | // [NullPtr] 30 | #if !ASMJIT_CC_HAS_NULLPTR && !defined(nullptr) 31 | # define nullptr NULL 32 | # define ASMJIT_UNDEF_NULLPTR 33 | #endif // !ASMJIT_CC_HAS_NULLPTR && !nullptr 34 | 35 | // [Override] 36 | #if !ASMJIT_CC_HAS_OVERRIDE && !defined(override) 37 | # define override 38 | # define ASMJIT_UNDEF_OVERRIDE 39 | #endif // !ASMJIT_CC_HAS_OVERRIDE && !override 40 | 41 | // ============================================================================ 42 | // [Compiler Support] 43 | // ============================================================================ 44 | 45 | // [Clang] 46 | #if ASMJIT_CC_CLANG 47 | # pragma clang diagnostic push 48 | # pragma clang diagnostic ignored "-Wc++11-extensions" 49 | # pragma clang diagnostic ignored "-Wconstant-logical-operand" 50 | # pragma clang diagnostic ignored "-Wunnamed-type-template-args" 51 | #endif // ASMJIT_CC_CLANG 52 | 53 | // [GCC] 54 | #if ASMJIT_CC_GCC 55 | # pragma GCC diagnostic push 56 | #endif // ASMJIT_CC_GCC 57 | 58 | // [MSC] 59 | #if ASMJIT_CC_MSC 60 | # pragma warning(push) 61 | # pragma warning(disable: 4127) // conditional expression is constant 62 | # pragma warning(disable: 4201) // nameless struct/union 63 | # pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible loss of data 64 | # pragma warning(disable: 4251) // struct needs to have dll-interface to be used by clients of struct ... 65 | # pragma warning(disable: 4275) // non dll-interface struct ... used as base for dll-interface struct 66 | # pragma warning(disable: 4355) // this used in base member initializer list 67 | # pragma warning(disable: 4480) // specifying underlying type for enum 68 | # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' 69 | # if _MSC_VER < 1900 70 | # if !defined(vsnprintf) 71 | # define ASMJIT_UNDEF_VSNPRINTF 72 | # define vsnprintf _vsnprintf 73 | # endif // !vsnprintf 74 | # if !defined(snprintf) 75 | # define ASMJIT_UNDEF_SNPRINTF 76 | # define snprintf _snprintf 77 | # endif // !snprintf 78 | # endif 79 | #endif // ASMJIT_CC_MSC 80 | 81 | // ============================================================================ 82 | // [Custom Macros] 83 | // ============================================================================ 84 | 85 | // [ASMJIT_NON...] 86 | #if ASMJIT_CC_HAS_DELETE_FUNCTION 87 | #define ASMJIT_NONCONSTRUCTIBLE(...) \ 88 | private: \ 89 | __VA_ARGS__() = delete; \ 90 | __VA_ARGS__(const __VA_ARGS__& other) = delete; \ 91 | __VA_ARGS__& operator=(const __VA_ARGS__& other) = delete; \ 92 | public: 93 | #define ASMJIT_NONCOPYABLE(...) \ 94 | private: \ 95 | __VA_ARGS__(const __VA_ARGS__& other) = delete; \ 96 | __VA_ARGS__& operator=(const __VA_ARGS__& other) = delete; \ 97 | public: 98 | #else 99 | #define ASMJIT_NONCONSTRUCTIBLE(...) \ 100 | private: \ 101 | inline __VA_ARGS__(); \ 102 | inline __VA_ARGS__(const __VA_ARGS__& other); \ 103 | inline __VA_ARGS__& operator=(const __VA_ARGS__& other); \ 104 | public: 105 | #define ASMJIT_NONCOPYABLE(...) \ 106 | private: \ 107 | inline __VA_ARGS__(const __VA_ARGS__& other); \ 108 | inline __VA_ARGS__& operator=(const __VA_ARGS__& other); \ 109 | public: 110 | #endif // ASMJIT_CC_HAS_DELETE_FUNCTION 111 | 112 | // [ASMJIT_ENUM] 113 | #if defined(_MSC_VER) && _MSC_VER >= 1400 114 | # define ASMJIT_ENUM(NAME) enum NAME : uint32_t 115 | #else 116 | # define ASMJIT_ENUM(NAME) enum NAME 117 | #endif 118 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/asmjit_apiend.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #if defined(ASMJIT_API_SCOPE) 9 | # undef ASMJIT_API_SCOPE 10 | #else 11 | # error "[asmjit] api-scope not active, forgot to include asmjit_apibegin.h?" 12 | #endif // ASMJIT_API_SCOPE 13 | 14 | // ============================================================================ 15 | // [C++ Support] 16 | // ============================================================================ 17 | 18 | // [NoExcept] 19 | #if defined(ASMJIT_UNDEF_NOEXCEPT) 20 | # undef noexcept 21 | # undef ASMJIT_UNDEF_NOEXCEPT 22 | #endif // ASMJIT_UNDEF_NOEXCEPT 23 | 24 | // [NullPtr] 25 | #if defined(ASMJIT_UNDEF_NULLPTR) 26 | # undef nullptr 27 | # undef ASMJIT_UNDEF_NULLPTR 28 | #endif // ASMJIT_UNDEF_NULLPTR 29 | 30 | // [Override] 31 | #if defined(ASMJIT_UNDEF_OVERRIDE) 32 | # undef override 33 | # undef ASMJIT_UNDEF_OVERRIDE 34 | #endif // ASMJIT_UNDEF_OVERRIDE 35 | 36 | // ============================================================================ 37 | // [Compiler Support] 38 | // ============================================================================ 39 | 40 | // [Clang] 41 | #if ASMJIT_CC_CLANG 42 | # pragma clang diagnostic pop 43 | #endif // ASMJIT_CC_CLANG 44 | 45 | // [GCC] 46 | #if ASMJIT_CC_GCC 47 | # pragma GCC diagnostic pop 48 | #endif // ASMJIT_CC_GCC 49 | 50 | // [MSC] 51 | #if ASMJIT_CC_MSC 52 | # pragma warning(pop) 53 | # if _MSC_VER < 1900 54 | # if defined(ASMJIT_UNDEF_VSNPRINTF) 55 | # undef vsnprintf 56 | # undef ASMJIT_UNDEF_VSNPRINTF 57 | # endif // ASMJIT_UNDEF_VSNPRINTF 58 | # if defined(ASMJIT_UNDEF_SNPRINTF) 59 | # undef snprintf 60 | # undef ASMJIT_UNDEF_SNPRINTF 61 | # endif // ASMJIT_UNDEF_SNPRINTF 62 | # endif 63 | #endif // ASMJIT_CC_MSC 64 | 65 | // ============================================================================ 66 | // [Custom Macros] 67 | // ============================================================================ 68 | 69 | // [ASMJIT_NON...] 70 | #undef ASMJIT_NONCONSTRUCTIBLE 71 | #undef ASMJIT_NONCOPYABLE 72 | 73 | // [ASMJIT_ENUM] 74 | #undef ASMJIT_ENUM 75 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_H 9 | #define _ASMJIT_BASE_H 10 | 11 | // [Dependencies] 12 | #include "./base/arch.h" 13 | #include "./base/assembler.h" 14 | #include "./base/codebuilder.h" 15 | #include "./base/codecompiler.h" 16 | #include "./base/codeemitter.h" 17 | #include "./base/codeholder.h" 18 | #include "./base/constpool.h" 19 | #include "./base/cpuinfo.h" 20 | #include "./base/func.h" 21 | #include "./base/globals.h" 22 | #include "./base/inst.h" 23 | #include "./base/logging.h" 24 | #include "./base/operand.h" 25 | #include "./base/osutils.h" 26 | #include "./base/runtime.h" 27 | #include "./base/simdtypes.h" 28 | #include "./base/string.h" 29 | #include "./base/utils.h" 30 | #include "./base/vmem.h" 31 | #include "./base/zone.h" 32 | 33 | // [Guard] 34 | #endif // _ASMJIT_BASE_H 35 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/arch.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies] 11 | #include "../base/arch.h" 12 | 13 | #if defined(ASMJIT_BUILD_X86) 14 | #include "../x86/x86operand.h" 15 | #endif // ASMJIT_BUILD_X86 16 | 17 | // [Api-Begin] 18 | #include "../asmjit_apibegin.h" 19 | 20 | namespace asmjit { 21 | 22 | // ============================================================================ 23 | // [asmjit::ArchInfo] 24 | // ============================================================================ 25 | 26 | static const uint32_t archInfoTable[] = { 27 | // <-------------+---------------------+-----------------------+-------+ 28 | // | Type | SubType | GPInfo| 29 | // <-------------+---------------------+-----------------------+-------+ 30 | ASMJIT_PACK32_4x8(ArchInfo::kTypeNone , ArchInfo::kSubTypeNone, 0, 0), 31 | ASMJIT_PACK32_4x8(ArchInfo::kTypeX86 , ArchInfo::kSubTypeNone, 4, 8), 32 | ASMJIT_PACK32_4x8(ArchInfo::kTypeX64 , ArchInfo::kSubTypeNone, 8, 16), 33 | ASMJIT_PACK32_4x8(ArchInfo::kTypeX32 , ArchInfo::kSubTypeNone, 8, 16), 34 | ASMJIT_PACK32_4x8(ArchInfo::kTypeA32 , ArchInfo::kSubTypeNone, 4, 16), 35 | ASMJIT_PACK32_4x8(ArchInfo::kTypeA64 , ArchInfo::kSubTypeNone, 8, 32) 36 | }; 37 | 38 | ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t type, uint32_t subType) noexcept { 39 | uint32_t index = type < ASMJIT_ARRAY_SIZE(archInfoTable) ? type : uint32_t(0); 40 | 41 | // Make sure the `archInfoTable` array is correctly indexed. 42 | _signature = archInfoTable[index]; 43 | ASMJIT_ASSERT(_type == index); 44 | 45 | // Even if the architecture is not known we setup its type and sub-type, 46 | // however, such architecture is not really useful. 47 | _type = type; 48 | _subType = subType; 49 | } 50 | 51 | // ============================================================================ 52 | // [asmjit::ArchUtils] 53 | // ============================================================================ 54 | 55 | ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept { 56 | uint32_t typeId = typeIdInOut; 57 | 58 | // Zero the signature so it's clear in case that typeId is not invalid. 59 | regInfo._signature = 0; 60 | 61 | #if defined(ASMJIT_BUILD_X86) 62 | if (ArchInfo::isX86Family(archType)) { 63 | // Passed RegType instead of TypeId? 64 | if (typeId <= Reg::kRegMax) 65 | typeId = x86OpData.archRegs.regTypeToTypeId[typeId]; 66 | 67 | if (ASMJIT_UNLIKELY(!TypeId::isValid(typeId))) 68 | return DebugUtils::errored(kErrorInvalidTypeId); 69 | 70 | // First normalize architecture dependent types. 71 | if (TypeId::isAbstract(typeId)) { 72 | if (typeId == TypeId::kIntPtr) 73 | typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kI32 : TypeId::kI64; 74 | else 75 | typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kU32 : TypeId::kU64; 76 | } 77 | 78 | // Type size helps to construct all kinds of registers. If the size is zero 79 | // then the TypeId is invalid. 80 | uint32_t size = TypeId::sizeOf(typeId); 81 | if (ASMJIT_UNLIKELY(!size)) 82 | return DebugUtils::errored(kErrorInvalidTypeId); 83 | 84 | if (ASMJIT_UNLIKELY(typeId == TypeId::kF80)) 85 | return DebugUtils::errored(kErrorInvalidUseOfF80); 86 | 87 | uint32_t regType = 0; 88 | 89 | switch (typeId) { 90 | case TypeId::kI8: 91 | case TypeId::kU8: 92 | regType = X86Reg::kRegGpbLo; 93 | break; 94 | 95 | case TypeId::kI16: 96 | case TypeId::kU16: 97 | regType = X86Reg::kRegGpw; 98 | break; 99 | 100 | case TypeId::kI32: 101 | case TypeId::kU32: 102 | regType = X86Reg::kRegGpd; 103 | break; 104 | 105 | case TypeId::kI64: 106 | case TypeId::kU64: 107 | if (archType == ArchInfo::kTypeX86) 108 | return DebugUtils::errored(kErrorInvalidUseOfGpq); 109 | 110 | regType = X86Reg::kRegGpq; 111 | break; 112 | 113 | // F32 and F64 are always promoted to use vector registers. 114 | case TypeId::kF32: 115 | typeId = TypeId::kF32x1; 116 | regType = X86Reg::kRegXmm; 117 | break; 118 | 119 | case TypeId::kF64: 120 | typeId = TypeId::kF64x1; 121 | regType = X86Reg::kRegXmm; 122 | break; 123 | 124 | // Mask registers {k}. 125 | case TypeId::kMask8: 126 | case TypeId::kMask16: 127 | case TypeId::kMask32: 128 | case TypeId::kMask64: 129 | regType = X86Reg::kRegK; 130 | break; 131 | 132 | // MMX registers. 133 | case TypeId::kMmx32: 134 | case TypeId::kMmx64: 135 | regType = X86Reg::kRegMm; 136 | break; 137 | 138 | // XMM|YMM|ZMM registers. 139 | default: 140 | if (size <= 16) 141 | regType = X86Reg::kRegXmm; 142 | else if (size == 32) 143 | regType = X86Reg::kRegYmm; 144 | else 145 | regType = X86Reg::kRegZmm; 146 | break; 147 | } 148 | 149 | typeIdInOut = typeId; 150 | regInfo._signature = x86OpData.archRegs.regInfo[regType].getSignature(); 151 | return kErrorOk; 152 | } 153 | #endif // ASMJIT_BUILD_X86 154 | 155 | return DebugUtils::errored(kErrorInvalidArch); 156 | } 157 | 158 | } // asmjit namespace 159 | 160 | // [Api-End] 161 | #include "../asmjit_apiend.h" 162 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/assembler.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_ASSEMBLER_H 9 | #define _ASMJIT_BASE_ASSEMBLER_H 10 | 11 | // [Dependencies] 12 | #include "../base/codeemitter.h" 13 | #include "../base/codeholder.h" 14 | #include "../base/operand.h" 15 | #include "../base/simdtypes.h" 16 | 17 | // [Api-Begin] 18 | #include "../asmjit_apibegin.h" 19 | 20 | namespace asmjit { 21 | 22 | //! \addtogroup asmjit_base 23 | //! \{ 24 | 25 | // ============================================================================ 26 | // [asmjit::Assembler] 27 | // ============================================================================ 28 | 29 | //! Base assembler. 30 | //! 31 | //! This class implements a base interface that is used by architecture 32 | //! specific assemblers. 33 | //! 34 | //! \sa CodeCompiler. 35 | class ASMJIT_VIRTAPI Assembler : public CodeEmitter { 36 | public: 37 | ASMJIT_NONCOPYABLE(Assembler) 38 | typedef CodeEmitter Base; 39 | 40 | // -------------------------------------------------------------------------- 41 | // [Construction / Destruction] 42 | // -------------------------------------------------------------------------- 43 | 44 | //! Create a new `Assembler` instance. 45 | ASMJIT_API Assembler() noexcept; 46 | //! Destroy the `Assembler` instance. 47 | ASMJIT_API virtual ~Assembler() noexcept; 48 | 49 | // -------------------------------------------------------------------------- 50 | // [Events] 51 | // -------------------------------------------------------------------------- 52 | 53 | ASMJIT_API Error onAttach(CodeHolder* code) noexcept override; 54 | ASMJIT_API Error onDetach(CodeHolder* code) noexcept override; 55 | 56 | // -------------------------------------------------------------------------- 57 | // [Code-Generation] 58 | // -------------------------------------------------------------------------- 59 | 60 | using CodeEmitter::_emit; 61 | 62 | ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) override; 63 | ASMJIT_API Error _emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) override; 64 | 65 | // -------------------------------------------------------------------------- 66 | // [Code-Buffer] 67 | // -------------------------------------------------------------------------- 68 | 69 | //! Called by \ref CodeHolder::sync(). 70 | ASMJIT_API virtual void sync() noexcept; 71 | 72 | //! Get the capacity of the current CodeBuffer. 73 | ASMJIT_INLINE size_t getBufferCapacity() const noexcept { return (size_t)(_bufferEnd - _bufferData); } 74 | //! Get the number of remaining bytes in the current CodeBuffer. 75 | ASMJIT_INLINE size_t getRemainingSpace() const noexcept { return (size_t)(_bufferEnd - _bufferPtr); } 76 | 77 | //! Get the current position in the CodeBuffer. 78 | ASMJIT_INLINE size_t getOffset() const noexcept { return (size_t)(_bufferPtr - _bufferData); } 79 | //! Set the current position in the CodeBuffer to `offset`. 80 | //! 81 | //! NOTE: The `offset` cannot be outside of the buffer length (even if it's 82 | //! within buffer's capacity). 83 | ASMJIT_API Error setOffset(size_t offset); 84 | 85 | //! Get start of the CodeBuffer of the current section. 86 | ASMJIT_INLINE uint8_t* getBufferData() const noexcept { return _bufferData; } 87 | //! Get end (first invalid byte) of the current section. 88 | ASMJIT_INLINE uint8_t* getBufferEnd() const noexcept { return _bufferEnd; } 89 | //! Get pointer in the CodeBuffer of the current section. 90 | ASMJIT_INLINE uint8_t* getBufferPtr() const noexcept { return _bufferPtr; } 91 | 92 | // -------------------------------------------------------------------------- 93 | // [Code-Generation] 94 | // -------------------------------------------------------------------------- 95 | 96 | ASMJIT_API Label newLabel() override; 97 | ASMJIT_API Label newNamedLabel( 98 | const char* name, 99 | size_t nameLength = Globals::kInvalidIndex, 100 | uint32_t type = Label::kTypeGlobal, 101 | uint32_t parentId = 0) override; 102 | ASMJIT_API Error bind(const Label& label) override; 103 | ASMJIT_API Error embed(const void* data, uint32_t size) override; 104 | ASMJIT_API Error embedLabel(const Label& label) override; 105 | ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override; 106 | ASMJIT_API Error comment(const char* s, size_t len = Globals::kInvalidIndex) override; 107 | 108 | // -------------------------------------------------------------------------- 109 | // [Emit-Helpers] 110 | // -------------------------------------------------------------------------- 111 | 112 | protected: 113 | #if !defined(ASMJIT_DISABLE_LOGGING) 114 | void _emitLog( 115 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, 116 | uint32_t relSize, uint32_t imLen, uint8_t* afterCursor); 117 | 118 | Error _emitFailed( 119 | Error err, 120 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3); 121 | #else 122 | ASMJIT_INLINE Error _emitFailed( 123 | uint32_t err, 124 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) { 125 | 126 | resetOptions(); 127 | resetInlineComment(); 128 | return setLastError(err); 129 | } 130 | #endif 131 | 132 | // -------------------------------------------------------------------------- 133 | // [Members] 134 | // -------------------------------------------------------------------------- 135 | 136 | public: 137 | SectionEntry* _section; //!< Current section where the assembling happens. 138 | uint8_t* _bufferData; //!< Start of the CodeBuffer of the current section. 139 | uint8_t* _bufferEnd; //!< End (first invalid byte) of the current section. 140 | uint8_t* _bufferPtr; //!< Pointer in the CodeBuffer of the current section. 141 | 142 | Operand_ _op4; //!< 5th operand data, used only temporarily. 143 | Operand_ _op5; //!< 6th operand data, used only temporarily. 144 | }; 145 | 146 | //! \} 147 | 148 | } // asmjit namespace 149 | 150 | // [Api-End] 151 | #include "../asmjit_apiend.h" 152 | 153 | // [Guard] 154 | #endif // _ASMJIT_BASE_ASSEMBLER_H 155 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/func.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies] 11 | #include "../base/arch.h" 12 | #include "../base/func.h" 13 | 14 | #if defined(ASMJIT_BUILD_X86) 15 | #include "../x86/x86internal_p.h" 16 | #include "../x86/x86operand.h" 17 | #endif // ASMJIT_BUILD_X86 18 | 19 | #if defined(ASMJIT_BUILD_ARM) 20 | #include "../arm/arminternal_p.h" 21 | #include "../arm/armoperand.h" 22 | #endif // ASMJIT_BUILD_ARM 23 | 24 | // [Api-Begin] 25 | #include "../asmjit_apibegin.h" 26 | 27 | namespace asmjit { 28 | 29 | // ============================================================================ 30 | // [asmjit::CallConv - Init / Reset] 31 | // ============================================================================ 32 | 33 | ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId) noexcept { 34 | reset(); 35 | 36 | #if defined(ASMJIT_BUILD_X86) 37 | if (CallConv::isX86Family(ccId)) 38 | return X86Internal::initCallConv(*this, ccId); 39 | #endif // ASMJIT_BUILD_X86 40 | 41 | #if defined(ASMJIT_BUILD_ARM) 42 | if (CallConv::isArmFamily(ccId)) 43 | return ArmInternal::initCallConv(*this, ccId); 44 | #endif // ASMJIT_BUILD_ARM 45 | 46 | return DebugUtils::errored(kErrorInvalidArgument); 47 | } 48 | 49 | // ============================================================================ 50 | // [asmjit::FuncDetail - Init / Reset] 51 | // ============================================================================ 52 | 53 | ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& sign) { 54 | uint32_t ccId = sign.getCallConv(); 55 | CallConv& cc = _callConv; 56 | 57 | uint32_t argCount = sign.getArgCount(); 58 | if (ASMJIT_UNLIKELY(argCount > kFuncArgCount)) 59 | return DebugUtils::errored(kErrorInvalidArgument); 60 | 61 | ASMJIT_PROPAGATE(cc.init(ccId)); 62 | 63 | uint32_t gpSize = (cc.getArchType() == ArchInfo::kTypeX86) ? 4 : 8; 64 | uint32_t deabstractDelta = TypeId::deabstractDeltaOfSize(gpSize); 65 | 66 | const uint8_t* args = sign.getArgs(); 67 | for (uint32_t i = 0; i < argCount; i++) { 68 | Value& arg = _args[i]; 69 | arg.initTypeId(TypeId::deabstract(args[i], deabstractDelta)); 70 | } 71 | _argCount = static_cast(argCount); 72 | 73 | uint32_t ret = sign.getRet(); 74 | if (ret != TypeId::kVoid) { 75 | _rets[0].initTypeId(TypeId::deabstract(ret, deabstractDelta)); 76 | _retCount = 1; 77 | } 78 | 79 | #if defined(ASMJIT_BUILD_X86) 80 | if (CallConv::isX86Family(ccId)) 81 | return X86Internal::initFuncDetail(*this, sign, gpSize); 82 | #endif // ASMJIT_BUILD_X86 83 | 84 | #if defined(ASMJIT_BUILD_ARM) 85 | if (CallConv::isArmFamily(ccId)) 86 | return ArmInternal::initFuncDetail(*this, sign, gpSize); 87 | #endif // ASMJIT_BUILD_ARM 88 | 89 | // We should never bubble here as if `cc.init()` succeeded then there has to 90 | // be an implementation for the current architecture. However, stay safe. 91 | return DebugUtils::errored(kErrorInvalidArgument); 92 | } 93 | 94 | // ============================================================================ 95 | // [asmjit::FuncFrameLayout - Init / Reset] 96 | // ============================================================================ 97 | 98 | ASMJIT_FAVOR_SIZE Error FuncFrameLayout::init(const FuncDetail& func, const FuncFrameInfo& ffi) noexcept { 99 | uint32_t ccId = func.getCallConv().getId(); 100 | 101 | #if defined(ASMJIT_BUILD_X86) 102 | if (CallConv::isX86Family(ccId)) 103 | return X86Internal::initFrameLayout(*this, func, ffi); 104 | #endif // ASMJIT_BUILD_X86 105 | 106 | #if defined(ASMJIT_BUILD_ARM) 107 | if (CallConv::isArmFamily(ccId)) 108 | return ArmInternal::initFrameLayout(*this, func, ffi); 109 | #endif // ASMJIT_BUILD_ARM 110 | 111 | return DebugUtils::errored(kErrorInvalidArgument); 112 | } 113 | 114 | // ============================================================================ 115 | // [asmjit::FuncArgsMapper] 116 | // ============================================================================ 117 | 118 | ASMJIT_FAVOR_SIZE Error FuncArgsMapper::updateFrameInfo(FuncFrameInfo& ffi) const noexcept { 119 | const FuncDetail* func = getFuncDetail(); 120 | if (!func) return DebugUtils::errored(kErrorInvalidState); 121 | 122 | uint32_t ccId = func->getCallConv().getId(); 123 | 124 | #if defined(ASMJIT_BUILD_X86) 125 | if (CallConv::isX86Family(ccId)) 126 | return X86Internal::argsToFrameInfo(*this, ffi); 127 | #endif // ASMJIT_BUILD_X86 128 | 129 | #if defined(ASMJIT_BUILD_ARM) 130 | if (CallConv::isArmFamily(ccId)) 131 | return ArmInternal::argsToFrameInfo(*this, ffi); 132 | #endif // ASMJIT_BUILD_X86 133 | 134 | return DebugUtils::errored(kErrorInvalidArch); 135 | } 136 | 137 | // ============================================================================ 138 | // [asmjit::FuncUtils] 139 | // ============================================================================ 140 | 141 | ASMJIT_FAVOR_SIZE Error FuncUtils::emitProlog(CodeEmitter* emitter, const FuncFrameLayout& layout) { 142 | #if defined(ASMJIT_BUILD_X86) 143 | if (emitter->getArchInfo().isX86Family()) 144 | return X86Internal::emitProlog(static_cast(emitter), layout); 145 | #endif // ASMJIT_BUILD_X86 146 | 147 | #if defined(ASMJIT_BUILD_ARM) 148 | if (emitter->getArchInfo().isArmFamily()) 149 | return ArmInternal::emitProlog(static_cast(emitter), layout); 150 | #endif // ASMJIT_BUILD_ARM 151 | 152 | return DebugUtils::errored(kErrorInvalidArch); 153 | } 154 | 155 | ASMJIT_FAVOR_SIZE Error FuncUtils::emitEpilog(CodeEmitter* emitter, const FuncFrameLayout& layout) { 156 | #if defined(ASMJIT_BUILD_X86) 157 | if (emitter->getArchInfo().isX86Family()) 158 | return X86Internal::emitEpilog(static_cast(emitter), layout); 159 | #endif // ASMJIT_BUILD_X86 160 | 161 | #if defined(ASMJIT_BUILD_ARM) 162 | if (emitter->getArchInfo().isArmFamily()) 163 | return ArmInternal::emitEpilog(static_cast(emitter), layout); 164 | #endif // ASMJIT_BUILD_ARM 165 | 166 | return DebugUtils::errored(kErrorInvalidArch); 167 | } 168 | 169 | ASMJIT_FAVOR_SIZE Error FuncUtils::allocArgs(CodeEmitter* emitter, const FuncFrameLayout& layout, const FuncArgsMapper& args) { 170 | #if defined(ASMJIT_BUILD_X86) 171 | if (emitter->getArchInfo().isX86Family()) 172 | return X86Internal::allocArgs(static_cast(emitter), layout, args); 173 | #endif // ASMJIT_BUILD_X86 174 | 175 | #if defined(ASMJIT_BUILD_ARM) 176 | if (emitter->getArchInfo().isArmFamily()) 177 | return ArmInternal::allocArgs(static_cast(emitter), layout, args); 178 | #endif // ASMJIT_BUILD_ARM 179 | 180 | return DebugUtils::errored(kErrorInvalidArch); 181 | } 182 | 183 | } // asmjit namespace 184 | 185 | // [Api-End] 186 | #include "../asmjit_apiend.h" 187 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/globals.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies] 11 | #include "../base/globals.h" 12 | #include "../base/utils.h" 13 | 14 | // [Api-Begin] 15 | #include "../asmjit_apibegin.h" 16 | 17 | namespace asmjit { 18 | 19 | // ============================================================================ 20 | // [asmjit::DebugUtils] 21 | // ============================================================================ 22 | 23 | #if !defined(ASMJIT_DISABLE_TEXT) 24 | static const char errorMessages[] = 25 | "Ok\0" 26 | "No heap memory\0" 27 | "No virtual memory\0" 28 | "Invalid argument\0" 29 | "Invalid state\0" 30 | "Invalid architecture\0" 31 | "Not initialized\0" 32 | "Already initialized\0" 33 | "Feature not enabled\0" 34 | "Slot occupied\0" 35 | "No code generated\0" 36 | "Code too large\0" 37 | "Invalid label\0" 38 | "Label index overflow\0" 39 | "Label already bound\0" 40 | "Label already defined\0" 41 | "Label name too long\0" 42 | "Invalid label name\0" 43 | "Invalid parent label\0" 44 | "Non-local label can't have parent\0" 45 | "Relocation index overflow\0" 46 | "Invalid relocation entry\0" 47 | "Invalid instruction\0" 48 | "Invalid register type\0" 49 | "Invalid register kind\0" 50 | "Invalid register's physical id\0" 51 | "Invalid register's virtual id\0" 52 | "Invalid prefix combination\0" 53 | "Invalid lock prefix\0" 54 | "Invalid xacquire prefix\0" 55 | "Invalid xrelease prefix\0" 56 | "Invalid rep prefix\0" 57 | "Invalid rex prefix\0" 58 | "Invalid mask, expected {k}\0" 59 | "Invalid use of {k}\0" 60 | "Invalid use of {k}{z}\0" 61 | "Invalid broadcast {1tox}\0" 62 | "Invalid {er} or {sae} option\0" 63 | "Invalid address\0" 64 | "Invalid address index\0" 65 | "Invalid address scale\0" 66 | "Invalid use of 64-bit address\0" 67 | "Invalid displacement\0" 68 | "Invalid segment\0" 69 | "Invalid immediate value\0" 70 | "Invalid operand size\0" 71 | "Ambiguous operand size\0" 72 | "Operand size mismatch\0" 73 | "Invalid type-info\0" 74 | "Invalid use of a low 8-bit GPB register\0" 75 | "Invalid use of a 64-bit GPQ register in 32-bit mode\0" 76 | "Invalid use of an 80-bit float\0" 77 | "Not consecutive registers\0" 78 | "No more physical registers\0" 79 | "Overlapped registers\0" 80 | "Overlapping register and arguments base-address register\0" 81 | "Unknown error\0"; 82 | #endif // ASMJIT_DISABLE_TEXT 83 | 84 | ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept { 85 | #if !defined(ASMJIT_DISABLE_TEXT) 86 | return Utils::findPackedString(errorMessages, std::min(err, kErrorCount)); 87 | #else 88 | static const char noMessage[] = ""; 89 | return noMessage; 90 | #endif 91 | } 92 | 93 | ASMJIT_FAVOR_SIZE void DebugUtils::debugOutput(const char* str) noexcept { 94 | #if ASMJIT_OS_WINDOWS 95 | ::OutputDebugStringA(str); 96 | #else 97 | ::fputs(str, stderr); 98 | #endif 99 | } 100 | 101 | ASMJIT_FAVOR_SIZE void DebugUtils::assertionFailed(const char* file, int line, const char* msg) noexcept { 102 | char str[1024]; 103 | 104 | snprintf(str, 1024, 105 | "[asmjit] Assertion failed at %s (line %d):\n" 106 | "[asmjit] %s\n", file, line, msg); 107 | 108 | // Support buggy `snprintf` implementations. 109 | str[1023] = '\0'; 110 | 111 | debugOutput(str); 112 | ::abort(); 113 | } 114 | 115 | } // asmjit namespace 116 | 117 | // [Api-End] 118 | #include "../asmjit_apiend.h" 119 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/inst.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Guard] 11 | #include "../asmjit_build.h" 12 | #if defined(ASMJIT_BUILD_X86) 13 | 14 | // [Dependencies] 15 | #include "../base/arch.h" 16 | #include "../base/inst.h" 17 | 18 | #if defined(ASMJIT_BUILD_X86) 19 | # include "../x86/x86instimpl_p.h" 20 | #endif // ASMJIT_BUILD_X86 21 | 22 | #if defined(ASMJIT_BUILD_ARM) 23 | # include "../arm/arminstimpl_p.h" 24 | #endif // ASMJIT_BUILD_ARM 25 | 26 | // [Api-Begin] 27 | #include "../asmjit_apibegin.h" 28 | 29 | namespace asmjit { 30 | 31 | // ============================================================================ 32 | // [asmjit::Inst - Validate] 33 | // ============================================================================ 34 | 35 | #if !defined(ASMJIT_DISABLE_VALIDATION) 36 | Error Inst::validate(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count) noexcept { 37 | #if defined(ASMJIT_BUILD_X86) 38 | if (ArchInfo::isX86Family(archType)) 39 | return X86InstImpl::validate(archType, detail, operands, count); 40 | #endif 41 | 42 | #if defined(ASMJIT_BUILD_ARM) 43 | if (ArchInfo::isArmFamily(archType)) 44 | return ArmInstImpl::validate(archType, detail, operands, count); 45 | #endif 46 | 47 | return DebugUtils::errored(kErrorInvalidArch); 48 | } 49 | #endif 50 | 51 | // ============================================================================ 52 | // [asmjit::Inst - CheckFeatures] 53 | // ============================================================================ 54 | 55 | #if !defined(ASMJIT_DISABLE_EXTENSIONS) 56 | Error Inst::checkFeatures(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count, CpuFeatures& out) noexcept { 57 | #if defined(ASMJIT_BUILD_X86) 58 | if (ArchInfo::isX86Family(archType)) 59 | return X86InstImpl::checkFeatures(archType, detail, operands, count, out); 60 | #endif 61 | 62 | #if defined(ASMJIT_BUILD_ARM) 63 | if (ArchInfo::isArmFamily(archType)) 64 | return ArmInstImpl::checkFeatures(archType, detail, operands, count, out); 65 | #endif 66 | 67 | return DebugUtils::errored(kErrorInvalidArch); 68 | } 69 | #endif // !defined(ASMJIT_DISABLE_EXTENSIONS) 70 | 71 | } // asmjit namespace 72 | 73 | // [Api-End] 74 | #include "../asmjit_apiend.h" 75 | 76 | // [Guard] 77 | #endif // ASMJIT_BUILD_X86 78 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/inst.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_INST_H 9 | #define _ASMJIT_BASE_INST_H 10 | 11 | // [Dependencies] 12 | #include "../base/cpuinfo.h" 13 | #include "../base/operand.h" 14 | 15 | // [Api-Begin] 16 | #include "../asmjit_apibegin.h" 17 | 18 | namespace asmjit { 19 | 20 | //! \addtogroup asmjit_base 21 | //! \{ 22 | 23 | // ============================================================================ 24 | // [asmjit::Inst] 25 | // ============================================================================ 26 | 27 | //! Definitions and utilities related to instructions used by all architectures. 28 | struct Inst { 29 | ASMJIT_ENUM(Id) { 30 | kIdNone = 0 //!< Invalid or uninitialized instruction id. 31 | }; 32 | 33 | //! Describes an instruction's jump type, if any. 34 | ASMJIT_ENUM(JumpType) { 35 | kJumpTypeNone = 0, //!< Instruction doesn't jump (regular instruction). 36 | kJumpTypeDirect = 1, //!< Instruction is a unconditional (direct) jump. 37 | kJumpTypeConditional = 2, //!< Instruction is a conditional jump. 38 | kJumpTypeCall = 3, //!< Instruction is a function call. 39 | kJumpTypeReturn = 4 //!< Instruction is a function return. 40 | }; 41 | 42 | // -------------------------------------------------------------------------- 43 | // [Detail] 44 | // -------------------------------------------------------------------------- 45 | 46 | //! Instruction id, options, and extraReg packed in a single structure. This 47 | //! structure exists to simplify analysis and validation API that requires a 48 | //! lot of information about the instruction to be processed. 49 | class Detail { 50 | public: 51 | ASMJIT_INLINE Detail() noexcept 52 | : instId(0), 53 | options(0), 54 | extraReg() {} 55 | 56 | explicit ASMJIT_INLINE Detail(uint32_t instId, uint32_t options = 0) noexcept 57 | : instId(instId), 58 | options(options), 59 | extraReg() {} 60 | 61 | ASMJIT_INLINE Detail(uint32_t instId, uint32_t options, const RegOnly& reg) noexcept 62 | : instId(instId), 63 | options(options), 64 | extraReg(reg) {} 65 | 66 | ASMJIT_INLINE Detail(uint32_t instId, uint32_t options, const Reg& reg) noexcept 67 | : instId(instId), 68 | options(options) { extraReg.init(reg); } 69 | 70 | // ------------------------------------------------------------------------ 71 | // [Accessors] 72 | // ------------------------------------------------------------------------ 73 | 74 | ASMJIT_INLINE bool hasExtraReg() const noexcept { return extraReg.isValid(); } 75 | 76 | // ------------------------------------------------------------------------ 77 | // [Members] 78 | // ------------------------------------------------------------------------ 79 | 80 | uint32_t instId; 81 | uint32_t options; 82 | RegOnly extraReg; 83 | }; 84 | 85 | // -------------------------------------------------------------------------- 86 | // [API] 87 | // -------------------------------------------------------------------------- 88 | 89 | #if !defined(ASMJIT_DISABLE_VALIDATION) 90 | //! Validate the given instruction. 91 | ASMJIT_API static Error validate(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count) noexcept; 92 | #endif // !ASMJIT_DISABLE_VALIDATION 93 | 94 | #if !defined(ASMJIT_DISABLE_EXTENSIONS) 95 | //! Check CPU features required to execute the given instruction. 96 | ASMJIT_API static Error checkFeatures(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count, CpuFeatures& out) noexcept; 97 | #endif // !defined(ASMJIT_DISABLE_EXTENSIONS) 98 | }; 99 | 100 | //! \} 101 | 102 | } // asmjit namespace 103 | 104 | // [Api-End] 105 | #include "../asmjit_apiend.h" 106 | 107 | // [Guard] 108 | #endif // _ASMJIT_BASE_INST_H 109 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/misc_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_MISC_P_H 9 | #define _ASMJIT_BASE_MISC_P_H 10 | 11 | // [Dependencies] 12 | #include "../asmjit_build.h" 13 | 14 | // [Api-Begin] 15 | #include "../asmjit_apibegin.h" 16 | 17 | namespace asmjit { 18 | 19 | //! \addtogroup asmjit_base 20 | //! \{ 21 | 22 | //! \internal 23 | //! 24 | //! Macro used to populate a table with 16 elements starting at `I`. 25 | #define ASMJIT_TABLE_16(DEF, I) DEF(I + 0), DEF(I + 1), DEF(I + 2), DEF(I + 3), \ 26 | DEF(I + 4), DEF(I + 5), DEF(I + 6), DEF(I + 7), \ 27 | DEF(I + 8), DEF(I + 9), DEF(I + 10), DEF(I + 11), \ 28 | DEF(I + 12), DEF(I + 13), DEF(I + 14), DEF(I + 15) 29 | 30 | #define ASMJIT_TABLE_T_8(TABLE, VALUE, I) \ 31 | TABLE< I + 0 >::VALUE, TABLE< I + 1 >::VALUE, \ 32 | TABLE< I + 2 >::VALUE, TABLE< I + 3 >::VALUE, \ 33 | TABLE< I + 4 >::VALUE, TABLE< I + 5 >::VALUE, \ 34 | TABLE< I + 6 >::VALUE, TABLE< I + 7 >::VALUE 35 | 36 | #define ASMJIT_TABLE_T_16(TABLE, VALUE, I) \ 37 | ASMJIT_TABLE_T_8(TABLE, VALUE, I), \ 38 | ASMJIT_TABLE_T_8(TABLE, VALUE, I + 8) 39 | 40 | #define ASMJIT_TABLE_T_32(TABLE, VALUE, I) \ 41 | ASMJIT_TABLE_T_16(TABLE, VALUE, I), \ 42 | ASMJIT_TABLE_T_16(TABLE, VALUE, I + 16) 43 | 44 | #define ASMJIT_TABLE_T_64(TABLE, VALUE, I) \ 45 | ASMJIT_TABLE_T_32(TABLE, VALUE, I), \ 46 | ASMJIT_TABLE_T_32(TABLE, VALUE, I + 32) 47 | 48 | #define ASMJIT_TABLE_T_128(TABLE, VALUE, I) \ 49 | ASMJIT_TABLE_T_64(TABLE, VALUE, I), \ 50 | ASMJIT_TABLE_T_64(TABLE, VALUE, I + 64) 51 | 52 | #define ASMJIT_TABLE_T_256(TABLE, VALUE, I) \ 53 | ASMJIT_TABLE_T_128(TABLE, VALUE, I), \ 54 | ASMJIT_TABLE_T_128(TABLE, VALUE, I + 128) 55 | 56 | #define ASMJIT_TABLE_T_512(TABLE, VALUE, I) \ 57 | ASMJIT_TABLE_T_256(TABLE, VALUE, I), \ 58 | ASMJIT_TABLE_T_256(TABLE, VALUE, I + 256) 59 | 60 | #define ASMJIT_TABLE_T_1024(TABLE, VALUE, I) \ 61 | ASMJIT_TABLE_T_512(TABLE, VALUE, I), \ 62 | ASMJIT_TABLE_T_512(TABLE, VALUE, I + 512) 63 | 64 | //! \} 65 | 66 | } // asmjit namespace 67 | 68 | //! \} 69 | 70 | // [Api-End] 71 | #include "../asmjit_apiend.h" 72 | 73 | // [Guard] 74 | #endif // _ASMJIT_BASE_MISC_P_H 75 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/osutils.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_OSUTILS_H 9 | #define _ASMJIT_BASE_OSUTILS_H 10 | 11 | // [Dependencies] 12 | #include "../base/globals.h" 13 | 14 | // [Api-Begin] 15 | #include "../asmjit_apibegin.h" 16 | 17 | namespace asmjit { 18 | 19 | //! \addtogroup asmjit_base 20 | //! \{ 21 | 22 | // ============================================================================ 23 | // [asmjit::VMemInfo] 24 | // ============================================================================ 25 | 26 | //! Information about OS virtual memory. 27 | struct VMemInfo { 28 | #if ASMJIT_OS_WINDOWS 29 | HANDLE hCurrentProcess; //!< Handle of the current process (Windows). 30 | #endif // ASMJIT_OS_WINDOWS 31 | size_t pageSize; //!< Virtual memory page size. 32 | size_t pageGranularity; //!< Virtual memory page granularity. 33 | }; 34 | 35 | // ============================================================================ 36 | // [asmjit::OSUtils] 37 | // ============================================================================ 38 | 39 | //! OS utilities. 40 | //! 41 | //! Virtual Memory 42 | //! -------------- 43 | //! 44 | //! Provides functions to allocate and release virtual memory that is required 45 | //! to execute dynamically generated code. If both processor and host OS support 46 | //! data-execution-prevention (DEP) then the only way to run machine code is to 47 | //! allocate virtual memory that has `OSUtils::kVMExecutable` flag enabled. All 48 | //! functions provides by OSUtils use internally platform specific API. 49 | //! 50 | //! Benchmarking 51 | //! ------------ 52 | //! 53 | //! OSUtils also provide a function `getTickCount()` that can be used for 54 | //! benchmarking purposes. It's similar to Windows-only `GetTickCount()`, but 55 | //! it's cross-platform and tries to be the most reliable platform specific 56 | //! calls to make the result usable. 57 | struct OSUtils { 58 | // -------------------------------------------------------------------------- 59 | // [Virtual Memory] 60 | // -------------------------------------------------------------------------- 61 | 62 | //! Virtual memory flags. 63 | ASMJIT_ENUM(VMFlags) { 64 | kVMWritable = 0x00000001U, //!< Virtual memory is writable. 65 | kVMExecutable = 0x00000002U //!< Virtual memory is executable. 66 | }; 67 | 68 | ASMJIT_API static VMemInfo getVirtualMemoryInfo() noexcept; 69 | 70 | //! Allocate virtual memory. 71 | ASMJIT_API static void* allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept; 72 | //! Release virtual memory previously allocated by \ref allocVirtualMemory(). 73 | ASMJIT_API static Error releaseVirtualMemory(void* p, size_t size) noexcept; 74 | 75 | #if ASMJIT_OS_WINDOWS 76 | //! Allocate virtual memory of `hProcess` (Windows). 77 | ASMJIT_API static void* allocProcessMemory(HANDLE hProcess, size_t size, size_t* allocated, uint32_t flags) noexcept; 78 | 79 | //! Release virtual memory of `hProcess` (Windows). 80 | ASMJIT_API static Error releaseProcessMemory(HANDLE hProcess, void* p, size_t size) noexcept; 81 | #endif // ASMJIT_OS_WINDOWS 82 | 83 | // -------------------------------------------------------------------------- 84 | // [GetTickCount] 85 | // -------------------------------------------------------------------------- 86 | 87 | //! Get the current CPU tick count, used for benchmarking (1ms resolution). 88 | ASMJIT_API static uint32_t getTickCount() noexcept; 89 | }; 90 | 91 | // ============================================================================ 92 | // [asmjit::Lock] 93 | // ============================================================================ 94 | 95 | //! \internal 96 | //! 97 | //! Lock. 98 | struct Lock { 99 | ASMJIT_NONCOPYABLE(Lock) 100 | 101 | // -------------------------------------------------------------------------- 102 | // [Windows] 103 | // -------------------------------------------------------------------------- 104 | 105 | #if ASMJIT_OS_WINDOWS 106 | typedef CRITICAL_SECTION Handle; 107 | 108 | //! Create a new `Lock` instance. 109 | ASMJIT_INLINE Lock() noexcept { InitializeCriticalSection(&_handle); } 110 | //! Destroy the `Lock` instance. 111 | ASMJIT_INLINE ~Lock() noexcept { DeleteCriticalSection(&_handle); } 112 | 113 | //! Lock. 114 | ASMJIT_INLINE void lock() noexcept { EnterCriticalSection(&_handle); } 115 | //! Unlock. 116 | ASMJIT_INLINE void unlock() noexcept { LeaveCriticalSection(&_handle); } 117 | #endif // ASMJIT_OS_WINDOWS 118 | 119 | // -------------------------------------------------------------------------- 120 | // [Posix] 121 | // -------------------------------------------------------------------------- 122 | 123 | #if ASMJIT_OS_POSIX 124 | typedef pthread_mutex_t Handle; 125 | 126 | //! Create a new `Lock` instance. 127 | ASMJIT_INLINE Lock() noexcept { pthread_mutex_init(&_handle, nullptr); } 128 | //! Destroy the `Lock` instance. 129 | ASMJIT_INLINE ~Lock() noexcept { pthread_mutex_destroy(&_handle); } 130 | 131 | //! Lock. 132 | ASMJIT_INLINE void lock() noexcept { pthread_mutex_lock(&_handle); } 133 | //! Unlock. 134 | ASMJIT_INLINE void unlock() noexcept { pthread_mutex_unlock(&_handle); } 135 | #endif // ASMJIT_OS_POSIX 136 | 137 | // -------------------------------------------------------------------------- 138 | // [Members] 139 | // -------------------------------------------------------------------------- 140 | 141 | //! Native handle. 142 | Handle _handle; 143 | }; 144 | 145 | // ============================================================================ 146 | // [asmjit::AutoLock] 147 | // ============================================================================ 148 | 149 | //! \internal 150 | //! 151 | //! Scoped lock. 152 | struct AutoLock { 153 | ASMJIT_NONCOPYABLE(AutoLock) 154 | 155 | // -------------------------------------------------------------------------- 156 | // [Construction / Destruction] 157 | // -------------------------------------------------------------------------- 158 | 159 | ASMJIT_INLINE AutoLock(Lock& target) noexcept : _target(target) { _target.lock(); } 160 | ASMJIT_INLINE ~AutoLock() noexcept { _target.unlock(); } 161 | 162 | // -------------------------------------------------------------------------- 163 | // [Members] 164 | // -------------------------------------------------------------------------- 165 | 166 | //! Reference to the `Lock`. 167 | Lock& _target; 168 | }; 169 | 170 | //! \} 171 | 172 | } // asmjit namespace 173 | 174 | // [Api-End] 175 | #include "../asmjit_apiend.h" 176 | 177 | // [Guard] 178 | #endif // _ASMJIT_BASE_OSUTILS_H 179 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/runtime.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies] 11 | #include "../base/assembler.h" 12 | #include "../base/cpuinfo.h" 13 | #include "../base/runtime.h" 14 | 15 | // [Api-Begin] 16 | #include "../asmjit_apibegin.h" 17 | 18 | namespace asmjit { 19 | 20 | static ASMJIT_INLINE void hostFlushInstructionCache(const void* p, size_t size) noexcept { 21 | // Only useful on non-x86 architectures. 22 | #if !ASMJIT_ARCH_X86 && !ASMJIT_ARCH_X64 23 | # if ASMJIT_OS_WINDOWS 24 | // Windows has a built-in support in kernel32.dll. 25 | ::FlushInstructionCache(_memMgr.getProcessHandle(), p, size); 26 | # endif // ASMJIT_OS_WINDOWS 27 | #else 28 | ASMJIT_UNUSED(p); 29 | ASMJIT_UNUSED(size); 30 | #endif // !ASMJIT_ARCH_X86 && !ASMJIT_ARCH_X64 31 | } 32 | 33 | static ASMJIT_INLINE uint32_t hostDetectNaturalStackAlignment() noexcept { 34 | // Alignment is assumed to match the pointer-size by default. 35 | uint32_t alignment = sizeof(intptr_t); 36 | 37 | // X86 & X64 38 | // --------- 39 | // 40 | // - 32-bit X86 requires stack to be aligned to 4 bytes. Modern Linux, Mac 41 | // and UNIX guarantees 16-byte stack alignment even on 32-bit. I'm not 42 | // sure about all other UNIX operating systems, because 16-byte alignment 43 | //! is addition to an older specification. 44 | // - 64-bit X86 requires stack to be aligned to at least 16 bytes. 45 | #if ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64 46 | int kIsModernOS = ASMJIT_OS_LINUX || // Linux & ANDROID. 47 | ASMJIT_OS_MAC || // OSX and iOS. 48 | ASMJIT_OS_BSD ; // BSD variants. 49 | alignment = ASMJIT_ARCH_X64 || kIsModernOS ? 16 : 4; 50 | #endif 51 | 52 | // ARM32 & ARM64 53 | // ------------- 54 | // 55 | // - 32-bit ARM requires stack to be aligned to 8 bytes. 56 | // - 64-bit ARM requires stack to be aligned to 16 bytes. 57 | #if ASMJIT_ARCH_ARM32 || ASMJIT_ARCH_ARM64 58 | alignment = ASMJIT_ARCH_ARM32 ? 8 : 16; 59 | #endif 60 | 61 | return alignment; 62 | } 63 | 64 | 65 | // ============================================================================ 66 | // [asmjit::Runtime - Construction / Destruction] 67 | // ============================================================================ 68 | 69 | Runtime::Runtime() noexcept 70 | : _codeInfo(), 71 | _runtimeType(kRuntimeNone), 72 | _allocType(VMemMgr::kAllocFreeable) {} 73 | Runtime::~Runtime() noexcept {} 74 | 75 | // ============================================================================ 76 | // [asmjit::HostRuntime - Construction / Destruction] 77 | // ============================================================================ 78 | 79 | HostRuntime::HostRuntime() noexcept { 80 | _runtimeType = kRuntimeJit; 81 | 82 | // Setup the CodeInfo of this Runtime. 83 | _codeInfo._archInfo = CpuInfo::getHost().getArchInfo(); 84 | _codeInfo._stackAlignment = static_cast(hostDetectNaturalStackAlignment()); 85 | _codeInfo._cdeclCallConv = CallConv::kIdHostCDecl; 86 | _codeInfo._stdCallConv = CallConv::kIdHostStdCall; 87 | _codeInfo._fastCallConv = CallConv::kIdHostFastCall; 88 | } 89 | HostRuntime::~HostRuntime() noexcept {} 90 | 91 | // ============================================================================ 92 | // [asmjit::HostRuntime - Interface] 93 | // ============================================================================ 94 | 95 | void HostRuntime::flush(const void* p, size_t size) noexcept { 96 | hostFlushInstructionCache(p, size); 97 | } 98 | 99 | // ============================================================================ 100 | // [asmjit::JitRuntime - Construction / Destruction] 101 | // ============================================================================ 102 | 103 | JitRuntime::JitRuntime() noexcept {} 104 | JitRuntime::~JitRuntime() noexcept {} 105 | 106 | // ============================================================================ 107 | // [asmjit::JitRuntime - Interface] 108 | // ============================================================================ 109 | 110 | Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept { 111 | size_t codeSize = code->getCodeSize(); 112 | if (ASMJIT_UNLIKELY(codeSize == 0)) { 113 | *dst = nullptr; 114 | return DebugUtils::errored(kErrorNoCodeGenerated); 115 | } 116 | 117 | void* p = _memMgr.alloc(codeSize, getAllocType()); 118 | if (ASMJIT_UNLIKELY(!p)) { 119 | *dst = nullptr; 120 | return DebugUtils::errored(kErrorNoVirtualMemory); 121 | } 122 | 123 | // Relocate the code and release the unused memory back to `VMemMgr`. 124 | size_t relocSize = code->relocate(p); 125 | if (ASMJIT_UNLIKELY(relocSize == 0)) { 126 | *dst = nullptr; 127 | _memMgr.release(p); 128 | return DebugUtils::errored(kErrorInvalidState); 129 | } 130 | 131 | if (relocSize < codeSize) 132 | _memMgr.shrink(p, relocSize); 133 | 134 | flush(p, relocSize); 135 | *dst = p; 136 | 137 | return kErrorOk; 138 | } 139 | 140 | Error JitRuntime::_release(void* p) noexcept { 141 | return _memMgr.release(p); 142 | } 143 | 144 | } // asmjit namespace 145 | 146 | // [Api-End] 147 | #include "../asmjit_apiend.h" 148 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/base/vmem.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_VMEM_H 9 | #define _ASMJIT_BASE_VMEM_H 10 | 11 | // [Dependencies] 12 | #include "../base/globals.h" 13 | #include "../base/osutils.h" 14 | 15 | // [Api-Begin] 16 | #include "../asmjit_apibegin.h" 17 | 18 | namespace asmjit { 19 | 20 | //! \addtogroup asmjit_base 21 | //! \{ 22 | 23 | // ============================================================================ 24 | // [asmjit::VMemMgr] 25 | // ============================================================================ 26 | 27 | //! Reference implementation of memory manager that uses `VMemUtil` to allocate 28 | //! chunks of virtual memory and bit arrays to manage it. 29 | class VMemMgr { 30 | public: 31 | //! Type of virtual memory allocation, see `VMemMgr::alloc()`. 32 | ASMJIT_ENUM(AllocType) { 33 | //! Normal memory allocation, has to be freed by `VMemMgr::release()`. 34 | kAllocFreeable = 0, 35 | //! Allocate permanent memory, can't be freed. 36 | kAllocPermanent = 1 37 | }; 38 | 39 | // -------------------------------------------------------------------------- 40 | // [Construction / Destruction] 41 | // -------------------------------------------------------------------------- 42 | 43 | #if !ASMJIT_OS_WINDOWS 44 | //! Create a `VMemMgr` instance. 45 | ASMJIT_API VMemMgr() noexcept; 46 | #else 47 | //! Create a `VMemMgr` instance. 48 | //! 49 | //! NOTE: When running on Windows it's possible to specify a `hProcess` to 50 | //! be used for memory allocation. Using `hProcess` allows to allocate memory 51 | //! of a remote process. 52 | ASMJIT_API VMemMgr(HANDLE hProcess = static_cast(0)) noexcept; 53 | #endif // ASMJIT_OS_WINDOWS 54 | 55 | //! Destroy the `VMemMgr` instance and free all blocks. 56 | ASMJIT_API ~VMemMgr() noexcept; 57 | 58 | // -------------------------------------------------------------------------- 59 | // [Reset] 60 | // -------------------------------------------------------------------------- 61 | 62 | //! Free all allocated memory. 63 | ASMJIT_API void reset() noexcept; 64 | 65 | // -------------------------------------------------------------------------- 66 | // [Accessors] 67 | // -------------------------------------------------------------------------- 68 | 69 | #if ASMJIT_OS_WINDOWS 70 | //! Get the handle of the process memory manager is bound to. 71 | ASMJIT_INLINE HANDLE getProcessHandle() const noexcept { return _hProcess; } 72 | #endif // ASMJIT_OS_WINDOWS 73 | 74 | //! Get how many bytes are currently allocated. 75 | ASMJIT_INLINE size_t getAllocatedBytes() const noexcept { return _allocatedBytes; } 76 | //! Get how many bytes are currently used. 77 | ASMJIT_INLINE size_t getUsedBytes() const noexcept { return _usedBytes; } 78 | 79 | //! Get whether to keep allocated memory after the `VMemMgr` is destroyed. 80 | //! 81 | //! \sa \ref setKeepVirtualMemory. 82 | ASMJIT_INLINE bool getKeepVirtualMemory() const noexcept { return _keepVirtualMemory; } 83 | //! Set whether to keep allocated memory after the memory manager is destroyed. 84 | //! 85 | //! This method is usable when patching code of remote process. You need to 86 | //! allocate process memory, store generated assembler into it and patch the 87 | //! method you want to redirect (into your code). This method affects only 88 | //! VMemMgr destructor. After destruction all internal 89 | //! structures are freed, only the process virtual memory remains. 90 | //! 91 | //! NOTE: Memory allocated with kAllocPermanent is always kept. 92 | //! 93 | //! \sa \ref getKeepVirtualMemory. 94 | ASMJIT_INLINE void setKeepVirtualMemory(bool val) noexcept { _keepVirtualMemory = val; } 95 | 96 | // -------------------------------------------------------------------------- 97 | // [Alloc / Release] 98 | // -------------------------------------------------------------------------- 99 | 100 | //! Allocate a `size` bytes of virtual memory. 101 | //! 102 | //! Note that if you are implementing your own virtual memory manager then you 103 | //! can quitly ignore type of allocation. This is mainly for AsmJit to memory 104 | //! manager that allocated memory will be never freed. 105 | ASMJIT_API void* alloc(size_t size, uint32_t type = kAllocFreeable) noexcept; 106 | //! Free previously allocated memory at a given `address`. 107 | ASMJIT_API Error release(void* p) noexcept; 108 | //! Free extra memory allocated with `p`. 109 | ASMJIT_API Error shrink(void* p, size_t used) noexcept; 110 | 111 | // -------------------------------------------------------------------------- 112 | // [Members] 113 | // -------------------------------------------------------------------------- 114 | 115 | #if ASMJIT_OS_WINDOWS 116 | HANDLE _hProcess; //!< Process passed to `VirtualAllocEx` and `VirtualFree`. 117 | #endif // ASMJIT_OS_WINDOWS 118 | Lock _lock; //!< Lock to enable thread-safe functionality. 119 | 120 | size_t _blockSize; //!< Default block size. 121 | size_t _blockDensity; //!< Default block density. 122 | bool _keepVirtualMemory; //!< Keep virtual memory after destroyed. 123 | 124 | size_t _allocatedBytes; //!< How many bytes are currently allocated. 125 | size_t _usedBytes; //!< How many bytes are currently used. 126 | 127 | //! \internal 128 | //! \{ 129 | 130 | struct RbNode; 131 | struct MemNode; 132 | struct PermanentNode; 133 | 134 | // Memory nodes root. 135 | MemNode* _root; 136 | // Memory nodes list. 137 | MemNode* _first; 138 | MemNode* _last; 139 | MemNode* _optimal; 140 | // Permanent memory. 141 | PermanentNode* _permanent; 142 | 143 | //! \} 144 | }; 145 | 146 | //! \} 147 | 148 | } // asmjit namespace 149 | 150 | // [Api-End] 151 | #include "../asmjit_apiend.h" 152 | 153 | // [Guard] 154 | #endif // _ASMJIT_BASE_VMEM_H 155 | -------------------------------------------------------------------------------- /vendor/asmjit/src/asmjit/x86.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_X86_H 9 | #define _ASMJIT_X86_H 10 | 11 | // [Dependencies] 12 | #include "./base.h" 13 | 14 | #include "./x86/x86assembler.h" 15 | #include "./x86/x86builder.h" 16 | #include "./x86/x86compiler.h" 17 | #include "./x86/x86emitter.h" 18 | #include "./x86/x86inst.h" 19 | #include "./x86/x86misc.h" 20 | #include "./x86/x86operand.h" 21 | 22 | // [Guard] 23 | #endif // _ASMJIT_X86_H 24 | -------------------------------------------------------------------------------- /vendor/asmjit/test/asmjit.h: -------------------------------------------------------------------------------- 1 | #include "../src/asmjit/asmjit.h" 2 | -------------------------------------------------------------------------------- /vendor/asmjit/test/asmjit_bench_x86.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Dependencies] 8 | #include 9 | #include 10 | #include 11 | 12 | #include "./asmjit.h" 13 | #include "./asmjit_test_misc.h" 14 | #include "./asmjit_test_opcode.h" 15 | 16 | using namespace asmjit; 17 | 18 | // ============================================================================ 19 | // [Configuration] 20 | // ============================================================================ 21 | 22 | static const uint32_t kNumRepeats = 10; 23 | static const uint32_t kNumIterations = 5000; 24 | 25 | // ============================================================================ 26 | // [Performance] 27 | // ============================================================================ 28 | 29 | struct Performance { 30 | static inline uint32_t now() { 31 | return OSUtils::getTickCount(); 32 | } 33 | 34 | inline void reset() { 35 | tick = 0; 36 | best = 0xFFFFFFFF; 37 | } 38 | 39 | inline uint32_t start() { return (tick = now()); } 40 | inline uint32_t diff() const { return now() - tick; } 41 | 42 | inline uint32_t end() { 43 | tick = diff(); 44 | if (best > tick) 45 | best = tick; 46 | return tick; 47 | } 48 | 49 | uint32_t tick; 50 | uint32_t best; 51 | }; 52 | 53 | static double mbps(uint32_t time, size_t outputSize) { 54 | if (!time) return 0.0; 55 | 56 | double bytesTotal = static_cast(outputSize); 57 | return (bytesTotal * 1000) / (static_cast(time) * 1024 * 1024); 58 | } 59 | 60 | // ============================================================================ 61 | // [Main] 62 | // ============================================================================ 63 | 64 | #if defined(ASMJIT_BUILD_X86) 65 | static void benchX86(uint32_t archType) { 66 | CodeHolder code; 67 | Performance perf; 68 | 69 | X86Assembler a; 70 | X86Compiler cc; 71 | 72 | uint32_t r, i; 73 | const char* archName = archType == ArchInfo::kTypeX86 ? "X86" : "X64"; 74 | 75 | // -------------------------------------------------------------------------- 76 | // [Bench - Assembler] 77 | // -------------------------------------------------------------------------- 78 | 79 | size_t asmOutputSize = 0; 80 | size_t cmpOutputSize = 0; 81 | 82 | perf.reset(); 83 | for (r = 0; r < kNumRepeats; r++) { 84 | asmOutputSize = 0; 85 | perf.start(); 86 | for (i = 0; i < kNumIterations; i++) { 87 | code.init(CodeInfo(archType)); 88 | code.attach(&a); 89 | 90 | asmtest::generateOpcodes(a); 91 | asmOutputSize += code.getCodeSize(); 92 | 93 | code.reset(false); // Detaches `a`. 94 | } 95 | perf.end(); 96 | } 97 | 98 | printf("%-12s (%s) | Time: %-6u [ms] | Speed: %7.3f [MB/s]\n", 99 | "X86Assembler", archName, perf.best, mbps(perf.best, asmOutputSize)); 100 | 101 | // -------------------------------------------------------------------------- 102 | // [Bench - CodeBuilder] 103 | // -------------------------------------------------------------------------- 104 | 105 | // TODO: 106 | 107 | // -------------------------------------------------------------------------- 108 | // [Bench - CodeCompiler] 109 | // -------------------------------------------------------------------------- 110 | 111 | perf.reset(); 112 | for (r = 0; r < kNumRepeats; r++) { 113 | cmpOutputSize = 0; 114 | perf.start(); 115 | for (i = 0; i < kNumIterations; i++) { 116 | // NOTE: Since we don't have JitRuntime we don't know anything about 117 | // function calling conventions, which is required by generateAlphaBlend. 118 | // So we must setup this manually. 119 | CodeInfo ci(archType); 120 | ci.setCdeclCallConv(archType == ArchInfo::kTypeX86 ? CallConv::kIdX86CDecl : CallConv::kIdX86SysV64); 121 | 122 | code.init(ci); 123 | code.attach(&cc); 124 | 125 | asmtest::generateAlphaBlend(cc); 126 | cc.finalize(); 127 | cmpOutputSize += code.getCodeSize(); 128 | 129 | code.reset(false); // Detaches `cc`. 130 | } 131 | perf.end(); 132 | } 133 | 134 | printf("%-12s (%s) | Time: %-6u [ms] | Speed: %7.3f [MB/s]\n", 135 | "X86Compiler", archName, perf.best, mbps(perf.best, cmpOutputSize)); 136 | } 137 | #endif 138 | 139 | int main(int argc, char* argv[]) { 140 | #if defined(ASMJIT_BUILD_X86) 141 | benchX86(ArchInfo::kTypeX86); 142 | benchX86(ArchInfo::kTypeX64); 143 | #endif // ASMJIT_BUILD_X86 144 | 145 | return 0; 146 | } 147 | -------------------------------------------------------------------------------- /vendor/asmjit/test/asmjit_test_misc.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_TEST_MISC_H 9 | #define _ASMJIT_TEST_MISC_H 10 | 11 | // [Dependencies] 12 | #include "./asmjit.h" 13 | 14 | namespace asmtest { 15 | 16 | // Generate a typical alpha blend function using SSE2 instruction set. Used 17 | // for benchmarking and also in test86. The generated code should be stable 18 | // and fully functional. 19 | static void generateAlphaBlend(asmjit::X86Compiler& cc) { 20 | using namespace asmjit; 21 | using namespace asmjit::x86; 22 | 23 | X86Gp dst = cc.newIntPtr("dst"); 24 | X86Gp src = cc.newIntPtr("src"); 25 | 26 | X86Gp i = cc.newIntPtr("i"); 27 | X86Gp j = cc.newIntPtr("j"); 28 | X86Gp t = cc.newIntPtr("t"); 29 | 30 | X86Xmm x0 = cc.newXmm("x0"); 31 | X86Xmm x1 = cc.newXmm("x1"); 32 | X86Xmm y0 = cc.newXmm("y0"); 33 | X86Xmm a0 = cc.newXmm("a0"); 34 | X86Xmm a1 = cc.newXmm("a1"); 35 | 36 | X86Xmm cZero = cc.newXmm("cZero"); 37 | X86Xmm cMul255A = cc.newXmm("cMul255A"); 38 | X86Xmm cMul255M = cc.newXmm("cMul255M"); 39 | 40 | Label L_SmallLoop = cc.newLabel(); 41 | Label L_SmallEnd = cc.newLabel(); 42 | Label L_LargeLoop = cc.newLabel(); 43 | Label L_LargeEnd = cc.newLabel(); 44 | Label L_DataPool = cc.newLabel(); 45 | 46 | cc.addFunc(FuncSignature3(cc.getCodeInfo().getCdeclCallConv())); 47 | 48 | cc.setArg(0, dst); 49 | cc.setArg(1, src); 50 | cc.setArg(2, i); 51 | 52 | cc.alloc(dst); 53 | cc.alloc(src); 54 | cc.alloc(i); 55 | 56 | // How many pixels have to be processed to make the loop aligned. 57 | cc.lea(t, ptr(L_DataPool)); 58 | cc.xor_(j, j); 59 | cc.xorps(cZero, cZero); 60 | 61 | cc.sub(j, dst); 62 | cc.movaps(cMul255A, ptr(t, 0)); 63 | 64 | cc.and_(j, 15); 65 | cc.movaps(cMul255M, ptr(t, 16)); 66 | 67 | cc.shr(j, 2); 68 | cc.jz(L_SmallEnd); 69 | 70 | // j = min(i, j). 71 | cc.cmp(j, i); 72 | cc.cmovg(j, i); 73 | 74 | // i -= j. 75 | cc.sub(i, j); 76 | 77 | // Small loop. 78 | cc.bind(L_SmallLoop); 79 | 80 | cc.pcmpeqb(a0, a0); 81 | cc.movd(y0, ptr(src)); 82 | 83 | cc.pxor(a0, y0); 84 | cc.movd(x0, ptr(dst)); 85 | 86 | cc.psrlw(a0, 8); 87 | cc.punpcklbw(x0, cZero); 88 | 89 | cc.pshuflw(a0, a0, x86::shufImm(1, 1, 1, 1)); 90 | cc.punpcklbw(y0, cZero); 91 | 92 | cc.pmullw(x0, a0); 93 | cc.paddsw(x0, cMul255A); 94 | cc.pmulhuw(x0, cMul255M); 95 | 96 | cc.paddw(x0, y0); 97 | cc.packuswb(x0, x0); 98 | 99 | cc.movd(ptr(dst), x0); 100 | 101 | cc.add(dst, 4); 102 | cc.add(src, 4); 103 | 104 | cc.dec(j); 105 | cc.jnz(L_SmallLoop); 106 | 107 | // Second section, prepare for an aligned loop. 108 | cc.bind(L_SmallEnd); 109 | 110 | cc.test(i, i); 111 | cc.mov(j, i); 112 | cc.jz(cc.getFunc()->getExitLabel()); 113 | 114 | cc.and_(j, 3); 115 | cc.shr(i, 2); 116 | cc.jz(L_LargeEnd); 117 | 118 | // Aligned loop. 119 | cc.bind(L_LargeLoop); 120 | 121 | cc.movups(y0, ptr(src)); 122 | cc.pcmpeqb(a0, a0); 123 | cc.movaps(x0, ptr(dst)); 124 | 125 | cc.xorps(a0, y0); 126 | cc.movaps(x1, x0); 127 | 128 | cc.psrlw(a0, 8); 129 | cc.punpcklbw(x0, cZero); 130 | 131 | cc.movaps(a1, a0); 132 | cc.punpcklwd(a0, a0); 133 | 134 | cc.punpckhbw(x1, cZero); 135 | cc.punpckhwd(a1, a1); 136 | 137 | cc.pshufd(a0, a0, x86::shufImm(3, 3, 1, 1)); 138 | cc.pshufd(a1, a1, x86::shufImm(3, 3, 1, 1)); 139 | 140 | cc.pmullw(x0, a0); 141 | cc.pmullw(x1, a1); 142 | 143 | cc.paddsw(x0, cMul255A); 144 | cc.paddsw(x1, cMul255A); 145 | 146 | cc.pmulhuw(x0, cMul255M); 147 | cc.pmulhuw(x1, cMul255M); 148 | 149 | cc.add(src, 16); 150 | cc.packuswb(x0, x1); 151 | 152 | cc.paddw(x0, y0); 153 | cc.movaps(ptr(dst), x0); 154 | 155 | cc.add(dst, 16); 156 | 157 | cc.dec(i); 158 | cc.jnz(L_LargeLoop); 159 | 160 | cc.bind(L_LargeEnd); 161 | cc.test(j, j); 162 | cc.jnz(L_SmallLoop); 163 | 164 | cc.endFunc(); 165 | 166 | // Data. 167 | cc.align(kAlignData, 16); 168 | cc.bind(L_DataPool); 169 | cc.dxmm(Data128::fromI16(0x0080)); 170 | cc.dxmm(Data128::fromI16(0x0101)); 171 | } 172 | 173 | } // asmtest namespace 174 | 175 | // [Guard] 176 | #endif // _ASMJIT_TEST_MISC_H 177 | -------------------------------------------------------------------------------- /vendor/asmjit/test/asmjit_test_opcode.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // This file is used to test opcodes generated by AsmJit. Output can be 8 | // disassembled in your IDE or by your favorite disassembler. Instructions 9 | // are grouped by category and then sorted alphabetically. 10 | 11 | // [Dependencies] 12 | #include 13 | #include 14 | #include 15 | 16 | #include "./asmjit.h" 17 | #include "./asmjit_test_opcode.h" 18 | 19 | using namespace asmjit; 20 | 21 | struct OpcodeDumpInfo { 22 | uint32_t archType; 23 | bool useRex1; 24 | bool useRex2; 25 | }; 26 | 27 | static const char* archTypeToString(uint32_t archType) { 28 | switch (archType) { 29 | case ArchInfo::kTypeNone : return "None"; 30 | case ArchInfo::kTypeX86 : return "X86"; 31 | case ArchInfo::kTypeX64 : return "X64"; 32 | case ArchInfo::kTypeA32 : return "A32"; 33 | case ArchInfo::kTypeA64 : return "A64"; 34 | 35 | default: 36 | return ""; 37 | } 38 | } 39 | 40 | struct TestErrorHandler : public ErrorHandler { 41 | virtual bool handleError(Error err, const char* message, CodeEmitter* origin) { 42 | printf("ERROR 0x%08X: %s\n", err, message); 43 | return true; 44 | } 45 | }; 46 | 47 | typedef void (*VoidFunc)(void); 48 | 49 | int main(int argc, char* argv[]) { 50 | TestErrorHandler eh; 51 | 52 | OpcodeDumpInfo infoList[] = { 53 | { ArchInfo::kTypeX86, false, false }, 54 | { ArchInfo::kTypeX64, false, false }, 55 | { ArchInfo::kTypeX64, false, true }, 56 | { ArchInfo::kTypeX64, true , false }, 57 | { ArchInfo::kTypeX64, true , true } 58 | }; 59 | 60 | for (int i = 0; i < ASMJIT_ARRAY_SIZE(infoList); i++) { 61 | const OpcodeDumpInfo& info = infoList[i]; 62 | 63 | printf("Opcodes [ARCH=%s REX1=%s REX2=%s]\n", 64 | archTypeToString(info.archType), 65 | info.useRex1 ? "true" : "false", 66 | info.useRex2 ? "true" : "false"); 67 | 68 | CodeHolder code; 69 | code.init(CodeInfo(info.archType)); 70 | code.setErrorHandler(&eh); 71 | 72 | #if !defined(ASMJIT_DISABLE_LOGGING) 73 | FileLogger logger(stdout); 74 | logger.addOptions(Logger::kOptionBinaryForm); 75 | code.setLogger(&logger); 76 | #endif // ASMJIT_DISABLE_LOGGING 77 | 78 | X86Assembler a(&code); 79 | asmtest::generateOpcodes(a, info.useRex1, info.useRex2); 80 | 81 | // If this is the host architecture the code generated can be executed 82 | // for debugging purposes (the first instruction is ret anyway). 83 | if (code.getArchType() == ArchInfo::kTypeHost) { 84 | JitRuntime runtime; 85 | VoidFunc p; 86 | Error err = runtime.add(&p, &code); 87 | if (err == kErrorOk) p(); 88 | } 89 | } 90 | 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /vendor/asmjit/test/asmjit_test_x86_asm.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Dependencies] 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "./asmjit.h" 14 | 15 | using namespace asmjit; 16 | 17 | // Signature of the generated function. 18 | typedef void (*SumIntsFunc)(int* dst, const int* a, const int* b); 19 | 20 | // This function works for both X86Assembler and X86Builder. It shows how 21 | // `X86Emitter` can be used to make your code more generic. 22 | static void makeFunc(X86Emitter* emitter) { 23 | // Decide which registers will be mapped to function arguments. Try changing 24 | // registers of `dst`, `src_a`, and `src_b` and see what happens in function's 25 | // prolog and epilog. 26 | X86Gp dst = emitter->zax(); 27 | X86Gp src_a = emitter->zcx(); 28 | X86Gp src_b = emitter->zdx(); 29 | 30 | // Decide which vector registers to use. We use these to keep the code generic, 31 | // you can switch to any other registers when needed. 32 | X86Xmm vec0 = x86::xmm0; 33 | X86Xmm vec1 = x86::xmm1; 34 | 35 | // Create and initialize `FuncDetail` and `FuncFrameInfo`. Both are 36 | // needed to create a function and they hold different kind of data. 37 | FuncDetail func; 38 | func.init(FuncSignature3(CallConv::kIdHost)); 39 | 40 | FuncFrameInfo ffi; 41 | ffi.setDirtyRegs(X86Reg::kKindVec, // Make XMM0 and XMM1 dirty. VEC kind 42 | Utils::mask(0, 1)); // describes XMM|YMM|ZMM registers. 43 | 44 | FuncArgsMapper args(&func); // Create function arguments mapper. 45 | args.assignAll(dst, src_a, src_b); // Assign our registers to arguments. 46 | args.updateFrameInfo(ffi); // Reflect our args in FuncFrameInfo. 47 | 48 | FuncFrameLayout layout; // Create the FuncFrameLayout, which 49 | layout.init(func, ffi); // contains metadata of prolog/epilog. 50 | 51 | // Emit function prolog and allocate arguments to registers. 52 | FuncUtils::emitProlog(emitter, layout); 53 | FuncUtils::allocArgs(emitter, layout, args); 54 | 55 | emitter->movdqu(vec0, x86::ptr(src_a)); // Load 4 ints from [src_a] to XMM0. 56 | emitter->movdqu(vec1, x86::ptr(src_b)); // Load 4 ints from [src_b] to XMM1. 57 | emitter->paddd(vec0, vec1); // Add 4 ints in XMM1 to XMM0. 58 | emitter->movdqu(x86::ptr(dst), vec0); // Store the result to [dst]. 59 | 60 | // Emit function epilog and return. 61 | FuncUtils::emitEpilog(emitter, layout); 62 | } 63 | 64 | int main(int argc, char* argv[]) { 65 | JitRuntime rt; // Create JIT Runtime 66 | 67 | CodeHolder code; // Create a CodeHolder. 68 | code.init(rt.getCodeInfo()); // Initialize it to match `rt`. 69 | X86Assembler a(&code); // Create and attach X86Assembler to `code`. 70 | 71 | FileLogger logger(stderr); 72 | code.setLogger(&logger); 73 | 74 | makeFunc(a.asEmitter()); 75 | 76 | SumIntsFunc fn; 77 | Error err = rt.add(&fn, &code); // Add the code generated to the runtime. 78 | if (err) return 1; // Handle a possible error case. 79 | 80 | // Execute the generated function. 81 | int inA[4] = { 4, 3, 2, 1 }; 82 | int inB[4] = { 1, 5, 2, 8 }; 83 | int out[4]; 84 | fn(out, inA, inB); 85 | 86 | // Prints {5 8 4 9} 87 | printf("{%d %d %d %d}\n", out[0], out[1], out[2], out[3]); 88 | 89 | rt.release(fn); 90 | 91 | if (out[0] == 5 && out[1] == 8 && out[2] == 4 && out[3] == 9) 92 | return 0; 93 | else 94 | return 1; 95 | } 96 | -------------------------------------------------------------------------------- /vendor/asmjit/test/broken.cpp: -------------------------------------------------------------------------------- 1 | // [Broken] 2 | // Lightweight Unit Testing for C++. 3 | // 4 | // [License] 5 | // Public Domain (Unlicense) 6 | 7 | // [Dependencies] 8 | #include "./broken.h" 9 | 10 | // ============================================================================ 11 | // [Broken - Global] 12 | // ============================================================================ 13 | 14 | // Zero initialized globals. 15 | struct BrokenGlobal { 16 | // -------------------------------------------------------------------------- 17 | // [Accessors] 18 | // -------------------------------------------------------------------------- 19 | 20 | bool hasArg(const char* a) const { 21 | int argc = _argc; 22 | const char** argv = _argv; 23 | 24 | for (int i = 1; i < argc; i++) { 25 | if (::strcmp(argv[i], a) == 0) 26 | return true; 27 | } 28 | 29 | return false; 30 | } 31 | 32 | FILE* getFile() const { 33 | return _file ? _file : stdout; 34 | } 35 | 36 | // -------------------------------------------------------------------------- 37 | // [Members] 38 | // -------------------------------------------------------------------------- 39 | 40 | // Application arguments. 41 | int _argc; 42 | const char** _argv; 43 | 44 | // Output file. 45 | FILE* _file; 46 | 47 | // Current context. 48 | const char* _currentFile; 49 | int _currentLine; 50 | 51 | // Unit tests. 52 | BrokenAPI::Unit* _unitList; 53 | BrokenAPI::Unit* _unitRunning; 54 | }; 55 | static BrokenGlobal _brokenGlobal; 56 | 57 | // ============================================================================ 58 | // [Broken - API] 59 | // ============================================================================ 60 | 61 | // Get whether the string `a` starts with string `b`. 62 | static bool BrokenAPI_startsWith(const char* a, const char* b) { 63 | for (size_t i = 0; ; i++) { 64 | if (b[i] == '\0') return true; 65 | if (a[i] != b[i]) return false; 66 | } 67 | } 68 | 69 | // Get whether the strings `a` and `b` are equal, ignoring case and treating 70 | // `-` as `_`. 71 | static bool BrokenAPI_matchesFilter(const char* a, const char* b) { 72 | for (size_t i = 0; ; i++) { 73 | unsigned char ca = static_cast(a[i]); 74 | unsigned char cb = static_cast(b[i]); 75 | 76 | // If filter is defined as wildcard the rest automatically matches. 77 | if (cb == '*') 78 | return true; 79 | 80 | if (ca == '-') ca = '_'; 81 | if (cb == '-') cb = '_'; 82 | 83 | if (ca >= 'A' && ca <= 'Z') ca += 'a' - 'A'; 84 | if (cb >= 'A' && cb <= 'Z') cb += 'a' - 'A'; 85 | 86 | if (ca != cb) 87 | return false; 88 | 89 | if (ca == '\0') 90 | return true; 91 | } 92 | } 93 | 94 | static bool BrokenAPI_canRun(BrokenAPI::Unit* unit) { 95 | BrokenGlobal& global = _brokenGlobal; 96 | 97 | int i, argc = global._argc; 98 | const char** argv = global._argv; 99 | 100 | const char* unitName = unit->name; 101 | bool hasFilter = false; 102 | 103 | for (i = 1; i < argc; i++) { 104 | const char* arg = argv[i]; 105 | 106 | if (BrokenAPI_startsWith(arg, "--run-") && ::strcmp(arg, "--run-all") != 0) { 107 | hasFilter = true; 108 | 109 | if (BrokenAPI_matchesFilter(unitName, arg + 6)) 110 | return true; 111 | } 112 | } 113 | 114 | // If no filter has been specified the default is to run. 115 | return !hasFilter; 116 | } 117 | 118 | static void BrokenAPI_runUnit(BrokenAPI::Unit* unit) { 119 | BrokenAPI::info("Running %s", unit->name); 120 | 121 | _brokenGlobal._unitRunning = unit; 122 | unit->entry(); 123 | _brokenGlobal._unitRunning = NULL; 124 | } 125 | 126 | static void BrokenAPI_runAll() { 127 | BrokenAPI::Unit* unit = _brokenGlobal._unitList; 128 | 129 | bool hasUnits = unit != NULL; 130 | size_t count = 0; 131 | 132 | while (unit != NULL) { 133 | if (BrokenAPI_canRun(unit)) { 134 | BrokenAPI_runUnit(unit); 135 | count++; 136 | } 137 | unit = unit->next; 138 | } 139 | 140 | if (count) { 141 | INFO("\nSuccess:"); 142 | INFO(" All tests passed!"); 143 | } 144 | else { 145 | INFO("\nWarning:"); 146 | INFO(" No units %s!", hasUnits ? "matched the filter" : "defined"); 147 | } 148 | } 149 | 150 | static void BrokenAPI_listAll() { 151 | BrokenAPI::Unit* unit = _brokenGlobal._unitList; 152 | 153 | if (unit != NULL) { 154 | INFO("Units:"); 155 | do { 156 | INFO(" %s", unit->name); 157 | unit = unit->next; 158 | } while (unit != NULL); 159 | } 160 | else { 161 | INFO("Warning:"); 162 | INFO(" No units defined!"); 163 | } 164 | } 165 | 166 | void BrokenAPI::add(Unit* unit) { 167 | Unit** pPrev = &_brokenGlobal._unitList; 168 | Unit* current = *pPrev; 169 | 170 | // C++ static initialization doesn't guarantee anything. We sort all units by 171 | // name so the execution will always happen in deterministic order. 172 | while (current != NULL) { 173 | if (::strcmp(current->name, unit->name) >= 0) 174 | break; 175 | 176 | pPrev = ¤t->next; 177 | current = *pPrev; 178 | } 179 | 180 | *pPrev = unit; 181 | unit->next = current; 182 | } 183 | 184 | void BrokenAPI::setOutputFile(FILE* file) { 185 | BrokenGlobal& global = _brokenGlobal; 186 | 187 | global._file = file; 188 | } 189 | 190 | int BrokenAPI::setContext(const char* file, int line) { 191 | BrokenGlobal& global = _brokenGlobal; 192 | 193 | global._currentFile = file; 194 | global._currentLine = line; 195 | 196 | return 1; 197 | } 198 | 199 | int BrokenAPI::run(int argc, const char* argv[], 200 | Entry onBeforeRun, 201 | Entry onAfterRun) { 202 | 203 | BrokenGlobal& global = _brokenGlobal; 204 | 205 | global._argc = argc; 206 | global._argv = argv; 207 | 208 | if (global.hasArg("--help")) { 209 | INFO("Options:"); 210 | INFO(" --help - print this usage"); 211 | INFO(" --list - list all tests"); 212 | INFO(" --run-... - run a test(s), trailing wildcards supported"); 213 | INFO(" --run-all - run all tests"); 214 | return 0; 215 | } 216 | 217 | if (global.hasArg("--list")) { 218 | BrokenAPI_listAll(); 219 | return 0; 220 | } 221 | 222 | if (onBeforeRun) 223 | onBeforeRun(); 224 | 225 | // We don't care about filters here, it's implemented by `runAll`. 226 | BrokenAPI_runAll(); 227 | 228 | if (onAfterRun) 229 | onAfterRun(); 230 | 231 | return 0; 232 | } 233 | 234 | int BrokenAPI::info(const char* fmt, ...) { 235 | BrokenGlobal& global = _brokenGlobal; 236 | FILE* dst = global.getFile(); 237 | 238 | const char* prefix = global._unitRunning ? " " : ""; 239 | size_t len = ::strlen(fmt); 240 | 241 | if (len != 0) { 242 | va_list ap; 243 | va_start(ap, fmt); 244 | ::fputs(prefix, dst); 245 | ::vfprintf(dst, fmt, ap); 246 | va_end(ap); 247 | } 248 | 249 | if (len == 0 || fmt[len - 1] != '\n') 250 | ::fputs("\n", dst); 251 | 252 | ::fflush(dst); 253 | return 1; 254 | } 255 | 256 | int BrokenAPI::fail(const char* fmt, va_list ap) { 257 | BrokenGlobal& global = _brokenGlobal; 258 | FILE* dst = global.getFile(); 259 | 260 | ::fputs(" Failed!", dst); 261 | if (fmt == NULL) 262 | fmt = ""; 263 | 264 | size_t len = ::strlen(fmt); 265 | if (len != 0) { 266 | ::fputs(" ", dst); 267 | ::vfprintf(dst, fmt, ap); 268 | } 269 | 270 | if (len > 0 && fmt[len - 1] != '\n') 271 | ::fputs("\n", dst); 272 | 273 | ::fprintf(dst, " File: %s (Line: %d)\n", global._currentFile, global._currentLine); 274 | ::fflush(dst); 275 | 276 | ::exit(1); 277 | return 1; 278 | } 279 | -------------------------------------------------------------------------------- /vendor/asmjit/test/broken.h: -------------------------------------------------------------------------------- 1 | // [Broken] 2 | // Lightweight Unit Testing for C++. 3 | // 4 | // [License] 5 | // Public Domain (Unlicense) 6 | 7 | // [Guard] 8 | #ifndef BROKEN_INTERNAL_H 9 | #define BROKEN_INTERNAL_H 10 | 11 | // [Dependencies] 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // ============================================================================ 18 | // [Broken - Detection] 19 | // ============================================================================ 20 | 21 | #if defined(__GNUC__) && defined(__GNUC_MINOR__) 22 | # if (__GNUC__ * 1000 + __GNUC_MINOR__) >= 3004 23 | # define BROKEN_NOINLINE __attribute__((__noinline__)) 24 | # endif 25 | #elif defined(__clang__) 26 | # if __has_attribute(__noinline__) 27 | # define BROKEN_NOINLINE __attribute__((__noinline__)) 28 | # endif 29 | #elif defined(_MSC_VER) 30 | # define __declspec(noinline) 31 | #endif 32 | 33 | #if !defined(BROKEN_NOINLINE) 34 | # define BROKEN_NOINLINE 35 | #endif 36 | 37 | // Hide everything when using Doxygen. Ideally this can be protected by a macro, 38 | // but there is not globally and widely used one across multiple projects. 39 | 40 | //! \internal 41 | //! \{ 42 | 43 | // ============================================================================ 44 | // [Broken - API] 45 | // ============================================================================ 46 | 47 | struct BrokenAPI { 48 | //! Entry point of a unit test defined by `UNIT` macro. 49 | typedef void (*Entry)(void); 50 | 51 | //! Test defined by `UNIT` macro. 52 | struct Unit { 53 | const char* name; 54 | Entry entry; 55 | size_t finished; 56 | Unit* next; 57 | }; 58 | 59 | //! Automatic unit registration by using static initialization. 60 | struct AutoUnit : Unit { 61 | inline AutoUnit(const char* _name, Entry _entry) { 62 | name = _name; 63 | entry = _entry; 64 | finished = false; 65 | next = NULL; 66 | 67 | BrokenAPI::add(this); 68 | } 69 | }; 70 | 71 | //! Register a new unit test (called automatically by `AutoUnit` and `UNIT`). 72 | static void add(Unit* unit); 73 | 74 | //! Set output file to a `file`. 75 | static void setOutputFile(FILE* file); 76 | 77 | //! Set the current context to `file` and `line`. 78 | //! 79 | //! This is called by `EXPECT` macro to set the correct `file` and `line`, 80 | //! because `EXPECT` macro internally calls `expect()` function, which does 81 | //! change the original file & line to non-interesting `broken.h`. 82 | static int setContext(const char* file, int line); 83 | 84 | //! Initialize `Broken` framework. 85 | //! 86 | //! Returns `true` if `run()` should be called. 87 | static int run(int argc, const char* argv[], 88 | Entry onBeforeRun = (Entry)NULL, 89 | Entry onAfterRun = (Entry)NULL); 90 | 91 | //! Used internally by `EXPECT` macro. 92 | template 93 | BROKEN_NOINLINE static int expect(const T& exp, const char* fmt = NULL, ...) { 94 | if (exp) 95 | return 1; 96 | 97 | va_list ap; 98 | va_start(ap, fmt); 99 | fail(fmt, ap); 100 | va_end(ap); 101 | return 0; 102 | } 103 | 104 | //! Log message, adds automatically new line if not present. 105 | static int info(const char* fmt, ...); 106 | //! Called on `EXPECT()` failure. 107 | static int fail(const char* fmt, va_list ap); 108 | }; 109 | 110 | // ============================================================================ 111 | // [Broken - Macros] 112 | // ============================================================================ 113 | 114 | //! Define a unit test. 115 | //! 116 | //! `_Name_` can only contain ASCII characters, numbers and underscore. It has 117 | //! the same rules as identifiers in C and C++. 118 | #define UNIT(_Name_) \ 119 | static void unit_##_Name_##_entry(void); \ 120 | \ 121 | static ::BrokenAPI::AutoUnit unit_##_Name_##_autoinit( \ 122 | #_Name_, unit_##_Name_##_entry); \ 123 | \ 124 | static void unit_##_Name_##_entry(void) 125 | 126 | //! #define INFO(...) 127 | //! 128 | //! Informative message printed to `stdout`. 129 | #define INFO ::BrokenAPI::setContext(__FILE__, __LINE__) && ::BrokenAPI::info 130 | 131 | //! #define INFO(_Exp_ [, _Format_ [, ...]]) 132 | //! 133 | //! Expect `_Exp_` to be true or evaluates to true, fail otherwise. 134 | #define EXPECT ::BrokenAPI::setContext(__FILE__, __LINE__) && ::BrokenAPI::expect 135 | 136 | // ============================================================================ 137 | // [Broken - Cleanup] 138 | // ============================================================================ 139 | 140 | #undef BROKEN_NOINLINE 141 | 142 | //! \} 143 | 144 | // [Guard] 145 | #endif // BROKEN_INTERNAL_H 146 | -------------------------------------------------------------------------------- /vendor/asmjitshared/build/asmjitshared.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 53 | 54 | -------------------------------------------------------------------------------- /vendor/asmjitshared/build/asmjitshared.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjitshared", "asmjitshared.vcxproj", "{7BA054CF-1A77-437D-8659-F2223380B2D5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Debug|x64.ActiveCfg = Debug|x64 17 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Debug|x64.Build.0 = Debug|x64 18 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Debug|x86.ActiveCfg = Debug|Win32 19 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Debug|x86.Build.0 = Debug|Win32 20 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Release|x64.ActiveCfg = Release|x64 21 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Release|x64.Build.0 = Release|x64 22 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Release|x86.ActiveCfg = Release|Win32 23 | {7BA054CF-1A77-437D-8659-F2223380B2D5}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /vendor/asmjitshared/build/asmjitshared.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /vendor/asmjitshared/build/makefile: -------------------------------------------------------------------------------- 1 | CC := g++ 2 | CCFLAGS := -std=c++17 3 | srcdir := $(CURDIR)/../src 4 | objdir := $(CURDIR)/../obj/linux 5 | sources := $(shell find $(srcdir) -name "*.cpp") 6 | headers := $(shell find $(srcdir) -name "*.h") $(shell find $(srcdir) -name "*.hxx") 7 | objects := $(patsubst $(srcdir)/%,$(objdir)/%.o,$(sources)) 8 | LIBMAKE = ar 9 | INCLUDE := \ 10 | -I$(CURDIR)/../../eirrepo/ \ 11 | -I$(CURDIR)/../../asmjit/src/ \ 12 | -I$(CURDIR)/../../peframework/include/ \ 13 | -I$(CURDIR)/../include/ 14 | 15 | main : $(objects) $(headers) ; mkdir -p ../lib/linux/ ; \ 16 | $(LIBMAKE) rcs ../lib/linux/libasmjitshared.a $(objects) 17 | 18 | $(objdir)/%.o : $(srcdir)/% ; \ 19 | mkdir -p $(dir $@) ; \ 20 | $(CC) -O3 -o $@ -c $< -Wno-invalid-offsetof $(INCLUDE) ; 21 | 22 | clean : ; \ 23 | rm -rf $(objdir) 24 | 25 | print-%: ; @echo '$*=$($*)' -------------------------------------------------------------------------------- /vendor/asmjitshared/include/asmjitshared.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASMJITSHARED_HEADER_ 2 | #define _ASMJITSHARED_HEADER_ 3 | 4 | // Common asmjit tools that I do not want to rewrite all the time. 5 | namespace asmjitshared 6 | { 7 | 8 | bool EmbedASMJITCodeIntoModule( 9 | PEFile& exeImage, bool requiresRelocations, const asmjit::CodeHolder& asmCodeHolder, const asmjit::Label& entryPointLabel, 10 | PEFile::PESectionDataReference& entryPointRefOut 11 | ); 12 | 13 | }; 14 | 15 | #endif //_ASMJITSHARED_HEADER_ -------------------------------------------------------------------------------- /vendor/eirrepo/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Martin Turski 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, including 5 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or 10 | substantial portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/AVLTree.helpers.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/AVLTree.helpers.h 6 | * PURPOSE: AVL-tree helper algorithms and structures 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _AVLTREE_HELPER_HEADER_ 14 | #define _AVLTREE_HELPER_HEADER_ 15 | 16 | #include "MacroUtils.h" 17 | #include "AVLTree.h" 18 | 19 | // Not placed in the main header because the difference of AVLTree types introduces great complexity. 20 | template 21 | AINLINE bool EqualsAVLTrees( leftAVLTreeType& left, rightAVLTreeType& right, const nodeComparatorType& cb ) 22 | { 23 | typename leftAVLTreeType::diff_node_iterator left_iter( left ); 24 | typename rightAVLTreeType::diff_node_iterator right_iter( right ); 25 | 26 | while ( true ) 27 | { 28 | bool isLeftEnd = left_iter.IsEnd(); 29 | bool isRightEnd = right_iter.IsEnd(); 30 | 31 | if ( isLeftEnd && isRightEnd ) 32 | { 33 | return true; 34 | } 35 | else if ( isLeftEnd || isRightEnd ) 36 | { 37 | return false; 38 | } 39 | 40 | // If any value is different then we do not match. 41 | const AVLNode *leftNode = left_iter.Resolve(); 42 | const AVLNode *rightNode = right_iter.Resolve(); 43 | 44 | if ( cb( leftNode, rightNode ) == false ) 45 | { 46 | return false; 47 | } 48 | 49 | left_iter.Increment(); 50 | right_iter.Increment(); 51 | } 52 | 53 | // Never reaches this point. 54 | return false; 55 | } 56 | 57 | #endif //_AVLTREE_HELPER_HEADER_ -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/DataUtil.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/DataUtil.h 6 | * PURPOSE: Simple helpers for memory operations 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _EIRREPO_DATA_UTILITIES_ 14 | #define _EIRREPO_DATA_UTILITIES_ 15 | 16 | #include 17 | 18 | #include "MacroUtils.h" 19 | 20 | // Some helpers. 21 | namespace FSDataUtil 22 | { 23 | template 24 | static inline void copy_impl( const dataType *srcPtr, const dataType *srcPtrEnd, dataType *dstPtr ) noexcept 25 | { 26 | static_assert( std::is_trivial ::value == true ); 27 | 28 | while ( srcPtr != srcPtrEnd ) 29 | { 30 | *dstPtr++ = *srcPtr++; 31 | } 32 | } 33 | 34 | template 35 | static inline void copy_backward_impl( const dataType *srcPtr, const dataType *srcPtrEnd, dataType *dstPtr ) noexcept 36 | { 37 | static_assert( std::is_trivial ::value == true ); 38 | 39 | while ( srcPtr != srcPtrEnd ) 40 | { 41 | *(--dstPtr) = *(--srcPtrEnd); 42 | } 43 | } 44 | }; 45 | 46 | namespace eir 47 | { 48 | 49 | template 50 | AINLINE unsignedNumberType ROTL( unsignedNumberType value, unsigned int rotBy ) 51 | { 52 | static constexpr unsigned int bitCount = sizeof(value) * 8; 53 | 54 | return ( value << rotBy ) | ( value >> ( bitCount - rotBy ) ); 55 | } 56 | template 57 | AINLINE unsignedNumberType ROTR( unsignedNumberType value, unsigned int rotBy ) 58 | { 59 | static constexpr unsigned int bitCount = sizeof(value) * 8; 60 | 61 | return ( value >> rotBy ) | ( value << ( bitCount - rotBy ) ); 62 | } 63 | 64 | }; 65 | 66 | #endif //_EIRREPO_DATA_UTILITIES_ -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/DynamicTypeSystem.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _memAlloc 6 | 7 | 8 | 9 | 10 | 11 | tinfoptr = (typeInfoBase*)( (char*)nodeptr - (unsigned int)&((typeInfoBase*)0)->node ) 12 | tinfoptr 13 | nodeptr = nodeptr->next 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/Endian.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/Endian.h 6 | * PURPOSE: Endianness utilities header 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _ENDIAN_COMPAT_HEADER_ 14 | #define _ENDIAN_COMPAT_HEADER_ 15 | 16 | #include "MacroUtils.h" 17 | 18 | // For the inline functions. 19 | #include 20 | 21 | namespace eir 22 | { 23 | 24 | // Endianness compatibility definitions. 25 | namespace endian 26 | { 27 | AINLINE static bool is_little_endian( void ) 28 | { 29 | // SHOULD be evaluating without runtime code. 30 | return ( *(unsigned short*)"\xFF\x00" == 0x00FF ); 31 | } 32 | 33 | template 34 | AINLINE numberType byte_swap_fast( const char *data ) 35 | { 36 | char swapped_data[ sizeof(numberType) ]; 37 | 38 | for ( unsigned int n = 0; n < sizeof(numberType); n++ ) 39 | { 40 | swapped_data[ n ] = data[ ( sizeof(numberType) - 1 ) - n ]; 41 | } 42 | 43 | return *(numberType*)swapped_data; 44 | } 45 | 46 | #ifdef _MSC_VER 47 | template <> AINLINE short byte_swap_fast( const char *data ) { return _byteswap_ushort( *(unsigned short*)data ); } 48 | template <> AINLINE unsigned short byte_swap_fast( const char *data ) { return _byteswap_ushort( *(unsigned short*)data ); } 49 | template <> AINLINE int byte_swap_fast( const char *data ) { return _byteswap_ulong( *(unsigned int*)data ); } 50 | template <> AINLINE unsigned int byte_swap_fast( const char *data ) { return _byteswap_ulong( *(unsigned int*)data ); } 51 | template <> AINLINE long byte_swap_fast( const char *data ) { return _byteswap_ulong( *(unsigned long*)data ); } 52 | template <> AINLINE unsigned long byte_swap_fast( const char *data ) { return _byteswap_ulong( *(unsigned long*)data ); } 53 | template <> AINLINE long long byte_swap_fast( const char *data ) { return _byteswap_uint64( *(unsigned long long*)data ); } 54 | template <> AINLINE unsigned long long byte_swap_fast( const char *data ) { return _byteswap_uint64( *(unsigned long long*)data ); } 55 | #elif defined(__linux__) 56 | template <> AINLINE short byte_swap_fast( const char *data ) { return __builtin_bswap16( *(unsigned short*)data ); } 57 | template <> AINLINE unsigned short byte_swap_fast( const char *data ) { return __builtin_bswap16( *(unsigned short*)data ); } 58 | template <> AINLINE int byte_swap_fast( const char *data ) { return __builtin_bswap32( *(unsigned int*)data ); } 59 | template <> AINLINE unsigned int byte_swap_fast( const char *data ) { return __builtin_bswap32( *(unsigned int*)data ); } 60 | template <> AINLINE long byte_swap_fast( const char *data ) { return __builtin_bswap32( *(unsigned long*)data ); } 61 | template <> AINLINE unsigned long byte_swap_fast( const char *data ) { return __builtin_bswap32( *(unsigned long*)data ); } 62 | template <> AINLINE long long byte_swap_fast( const char *data ) { return __builtin_bswap64( *(unsigned long long*)data ); } 63 | template <> AINLINE unsigned long long byte_swap_fast( const char *data ) { return __builtin_bswap64( *(unsigned long long*)data ); } 64 | #endif 65 | 66 | template 67 | struct big_endian 68 | { 69 | // Required to be default for POD handling. 70 | inline big_endian( void ) = default; 71 | inline big_endian( const big_endian& right ) = default; 72 | 73 | inline big_endian( numberType right ) 74 | { 75 | this->operator = ( right ); 76 | } 77 | 78 | inline operator numberType( void ) const noexcept 79 | { 80 | if ( is_little_endian() ) 81 | { 82 | return byte_swap_fast ( this->data ); 83 | } 84 | else 85 | { 86 | return *(numberType*)this->data; 87 | } 88 | } 89 | 90 | inline numberType operator = ( const numberType& right ) noexcept 91 | { 92 | if ( is_little_endian() ) 93 | { 94 | *(numberType*)data = byte_swap_fast ( (const char*)&right ); 95 | } 96 | else 97 | { 98 | *(numberType*)data = right; 99 | } 100 | 101 | return right; 102 | } 103 | 104 | inline big_endian& operator = ( const big_endian& right ) = default; 105 | 106 | private: 107 | char data[ sizeof(numberType) ]; 108 | }; 109 | 110 | template 111 | struct little_endian 112 | { 113 | // Required to be default for POD handling. 114 | inline little_endian( void ) = default; 115 | inline little_endian( const little_endian& right ) = default; 116 | 117 | inline little_endian( numberType right ) 118 | { 119 | this->operator = ( right ); 120 | } 121 | 122 | inline operator numberType( void ) const noexcept 123 | { 124 | if ( !is_little_endian() ) 125 | { 126 | return byte_swap_fast ( this->data ); 127 | } 128 | else 129 | { 130 | return *(numberType*)this->data; 131 | } 132 | } 133 | 134 | inline numberType operator = ( const numberType& right ) noexcept 135 | { 136 | if ( !is_little_endian() ) 137 | { 138 | *(numberType*)data = byte_swap_fast ( (const char*)&right ); 139 | } 140 | else 141 | { 142 | *(numberType*)data = right; 143 | } 144 | 145 | return right; 146 | } 147 | 148 | inline little_endian& operator = ( const little_endian& right ) = default; 149 | 150 | private: 151 | char data[ sizeof(numberType) ]; 152 | }; 153 | }; 154 | 155 | }; // namespace eir 156 | 157 | // For compatibility with older code. 158 | namespace endian = eir::endian; 159 | 160 | #endif //_ENDIAN_COMPAT_HEADER_ -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/Endian.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {*($T1*)data} 5 | 6 | *($T1*)data 7 | 8 | 9 | 10 | {*(unsigned char*)data} 11 | 12 | 13 | {*(char*)data} 14 | 15 | 16 | {(unsigned short)( ( ( *(unsigned short*)data & 0xFF00 ) >> 8 ) | ( ( *(unsigned short*)data & 0xFF ) << 8 ) )} 17 | 18 | 19 | {(short)( ( ( *(unsigned short*)data & 0xFF00 ) >> 8 ) | ( ( *(unsigned short*)data & 0xFF ) << 8 ) )} 20 | 21 | 22 | {(unsigned int)( ( ( *(unsigned int*)data & 0xFF000000 ) >> 24 ) | ( ( *(unsigned int*)data & 0xFF0000 ) >> 8 ) | ( ( *(unsigned int*)data & 0xFF00 ) << 8 ) | ( ( *(unsigned int*)data & 0xFF ) << 24 ) )} 23 | 24 | 25 | {(int)( ( ( *(unsigned int*)data & 0xFF000000 ) >> 24 ) | ( ( *(unsigned int*)data & 0xFF0000 ) >> 8 ) | ( ( *(unsigned int*)data & 0xFF00 ) << 8 ) | ( ( *(unsigned int*)data & 0xFF ) << 24 ) )} 26 | 27 | 28 | {(unsigned __int64)( ( ( *(unsigned __int64*)data & 0xFF00000000000000 ) >> 56 ) | ( ( *(unsigned __int64*)data & 0xFF000000000000 ) >> 40 ) | ( ( *(unsigned __int64*)data & 0xFF0000000000 ) >> 24 ) | ( ( *(unsigned __int64*)data & 0xFF00000000 ) >> 8 ) | ( ( *(unsigned __int64*)data & 0xFF000000 ) << 8 ) | ( ( *(unsigned __int64*)data & 0xFF0000 ) << 24 ) | ( ( *(unsigned __int64*)data & 0xFF00 ) << 40 ) | ( ( *(unsigned __int64*)data & 0xFF ) << 56 ) )} 29 | 30 | 31 | {(__int64)( ( ( *(unsigned __int64*)data & 0xFF00000000000000 ) >> 56 ) | ( ( *(unsigned __int64*)data & 0xFF000000000000 ) >> 40 ) | ( ( *(unsigned __int64*)data & 0xFF0000000000 ) >> 24 ) | ( ( *(unsigned __int64*)data & 0xFF00000000 ) >> 8 ) | ( ( *(unsigned __int64*)data & 0xFF000000 ) << 8 ) | ( ( *(unsigned __int64*)data & 0xFF0000 ) << 24 ) | ( ( *(unsigned __int64*)data & 0xFF00 ) << 40 ) | ( ( *(unsigned __int64*)data & 0xFF ) << 56 ) )} 32 | 33 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/Function.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/Function.h 6 | * PURPOSE: Dynamic function storage struct helper (i.e. lambdas) 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | // Motivation for adding this type was that the STL does not support providing 14 | // a custom allocator for std::function. 15 | 16 | #ifndef _DYNAMIC_FUNCTION_STORAGE_ 17 | #define _DYNAMIC_FUNCTION_STORAGE_ 18 | 19 | #include 20 | 21 | #include "MacroUtils.h" 22 | #include "eirutils.h" 23 | 24 | namespace eir 25 | { 26 | 27 | // TODO: add object-allocator support to eir::Function, refptr support, etc. 28 | 29 | template 30 | struct Function 31 | { 32 | AINLINE Function( void ) 33 | { 34 | this->func_mem = nullptr; 35 | } 36 | 37 | template 38 | AINLINE Function( callbackType&& cb ) 39 | { 40 | static_assert( std::is_invocable ::value, "lambda has to be invocable with the given cbArgs" ); 41 | static_assert( std::is_same ::type, returnType>::value, "lambda has to be invocable with given returnType" ); 42 | 43 | struct lambda_function_storage : public virtual_function_storage 44 | { 45 | AINLINE lambda_function_storage( callbackType&& cb ) : cb( std::move( cb ) ) 46 | { 47 | return; 48 | } 49 | 50 | AINLINE returnType invoke( cbArgs&&... args ) 51 | { 52 | return cb( std::forward ( args )... ); 53 | } 54 | 55 | callbackType cb; 56 | }; 57 | 58 | this->func_mem = static_new_struct ( nullptr, std::move( cb ) ); 59 | } 60 | AINLINE Function( const Function& right ) = delete; 61 | AINLINE Function( Function&& right ) noexcept 62 | { 63 | this->func_mem = right.func_mem; 64 | 65 | right.func_mem = nullptr; 66 | } 67 | 68 | private: 69 | AINLINE void _clear_mem( void ) 70 | { 71 | if ( virtual_function_storage *func_mem = this->func_mem ) 72 | { 73 | static_del_struct ( nullptr, func_mem ); 74 | 75 | this->func_mem = nullptr; 76 | } 77 | } 78 | 79 | public: 80 | AINLINE ~Function( void ) 81 | { 82 | _clear_mem(); 83 | } 84 | 85 | AINLINE Function& operator = ( const Function& ) = delete; 86 | AINLINE Function& operator = ( Function&& right ) noexcept 87 | { 88 | _clear_mem(); 89 | 90 | this->func_mem = right.func_mem; 91 | 92 | right.func_mem = nullptr; 93 | 94 | return *this; 95 | } 96 | 97 | AINLINE bool is_good( void ) const 98 | { 99 | return ( this->func_mem != nullptr ); 100 | } 101 | 102 | AINLINE returnType operator () ( cbArgs&&... args ) 103 | { 104 | virtual_function_storage *func_mem = this->func_mem; 105 | 106 | if ( func_mem == nullptr ) 107 | { 108 | throw eir_exception(); 109 | } 110 | 111 | return func_mem->invoke( std::forward ( args )... ); 112 | } 113 | 114 | private: 115 | struct virtual_function_storage 116 | { 117 | virtual ~virtual_function_storage( void ) 118 | { 119 | return; 120 | } 121 | 122 | virtual returnType invoke( cbArgs&&... args ) = 0; 123 | }; 124 | 125 | virtual_function_storage *func_mem; 126 | }; 127 | 128 | } 129 | 130 | #endif //_DYNAMIC_FUNCTION_STORAGE_ 131 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/MacroUtils.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/MacroUtils.h 6 | * PURPOSE: Common macros in the SDK 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _COMMON_MACRO_UTILITIES_ 14 | #define _COMMON_MACRO_UTILITIES_ 15 | 16 | // Basic always inline definition. 17 | #ifndef AINLINE 18 | #ifdef _MSC_VER 19 | #define AINLINE __forceinline 20 | #elif __linux__ 21 | #define AINLINE inline 22 | #else 23 | #define AINLINE inline 24 | #endif 25 | #endif 26 | 27 | #ifndef _MSC_VER 28 | #define abstract 29 | #endif 30 | 31 | #ifndef countof 32 | #define countof(x) (sizeof(x)/sizeof(*x)) 33 | #endif 34 | 35 | #endif //_COMMON_MACRO_UTILITIES_ -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/MemoryRaw.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/MemoryRaw.h 6 | * PURPOSE: Base memory management definitions for to-the-metal things 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _MEMORY_RAW_DEFS_ 14 | #define _MEMORY_RAW_DEFS_ 15 | 16 | #include "MathSlice.h" 17 | 18 | // Mathematically correct data slice logic. 19 | // It is one of the most important theorems in computing abstraction. 20 | // TODO: limit this type to integral things only. 21 | template 22 | using sliceOfData = eir::mathSlice ; 23 | 24 | #include 25 | 26 | // Macro that defines how alignment works. 27 | // num: base of the number to be aligned 28 | // sector: aligned-offset that should be added to num 29 | // align: number of bytes to align to 30 | // EXAMPLE: ALIGN( 0x1001, 4, 4 ) -> 0x1000 (equivalent of compiler structure padding alignment) 31 | // ALIGN( 0x1003, 1, 4 ) -> 0x1000 32 | // ALIGN( 0x1003, 2, 4 ) -> 0x1004 33 | template 34 | AINLINE numberType _ALIGN_GP( numberType num, numberType sector, numberType align ) 35 | { 36 | // General purpose alignment routine. 37 | // Not as fast as the bitfield version. 38 | numberType sectorOffset = ((num) + (sector) - 1); 39 | 40 | return sectorOffset - ( sectorOffset % align ); 41 | } 42 | 43 | template 44 | AINLINE numberType _ALIGN_NATIVE( numberType num, numberType sector, numberType align ) 45 | { 46 | const size_t bitCount = sizeof( align ) * 8; 47 | 48 | // assume math based on x86 bits. 49 | if ( std::bitset ( align ).count() == 1 ) 50 | { 51 | //bitfield version. not compatible with non-bitfield alignments. 52 | return (((num) + (sector) - 1) & (~((align) - 1))); 53 | } 54 | else 55 | { 56 | return _ALIGN_GP( num, sector, align ); 57 | } 58 | } 59 | 60 | template 61 | AINLINE numberType ALIGN( numberType num, numberType sector, numberType align ) 62 | { 63 | return _ALIGN_GP( num, sector, align ); 64 | } 65 | 66 | // Optimized primitives. 67 | template <> AINLINE char ALIGN( char num, char sector, char align ) { return _ALIGN_NATIVE( num, sector, align ); } 68 | template <> AINLINE unsigned char ALIGN( unsigned char num, unsigned char sector, unsigned char align ) { return _ALIGN_NATIVE( num, sector, align ); } 69 | template <> AINLINE short ALIGN( short num, short sector, short align ) { return _ALIGN_NATIVE( num, sector, align ); } 70 | template <> AINLINE unsigned short ALIGN( unsigned short num, unsigned short sector, unsigned short align ){ return _ALIGN_NATIVE( num, sector, align ); } 71 | template <> AINLINE int ALIGN( int num, int sector, int align ) { return _ALIGN_NATIVE( num, sector, align ); } 72 | template <> AINLINE unsigned int ALIGN( unsigned int num, unsigned int sector, unsigned int align ) 73 | { 74 | return (unsigned int)_ALIGN_NATIVE( (int)num, (int)sector, (int)align ); 75 | } 76 | 77 | // Helper macro (equivalent of EXAMPLE 1) 78 | template 79 | inline numberType ALIGN_SIZE( numberType num, numberType sector ) 80 | { 81 | return ( ALIGN( (num), (sector), (sector) ) ); 82 | } 83 | 84 | // Aligning thigns to the boundary below. 85 | template 86 | AINLINE numberType SCALE_DOWN( numberType value, numberType modval ) 87 | { 88 | // This is faster than divide-and-multiply, plus it does exactly the same. 89 | numberType rem = ( value % modval ); 90 | 91 | return ( value - rem ); 92 | } 93 | 94 | #endif //_MEMORY_RAW_DEFS_ -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/MemoryUtils.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | this->sizeCount 5 | this->numActiveEntries 6 | 7 | this->numActiveEntries 8 | this->data 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/MultiString.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {this->strData} 5 | 6 | this->strData 7 | 8 | 9 | 10 | {*this->data.strData} 11 | 12 | this->data.strData 13 | 14 | 15 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/OSUtils.vmem.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/OSUtils.vmem.h 6 | * PURPOSE: OS implementation of virtual memory mapping 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _NATIVE_OS_VIRTUAL_MEMORY_FUNCS_ 14 | #define _NATIVE_OS_VIRTUAL_MEMORY_FUNCS_ 15 | 16 | // For FATAL_ASSERT. 17 | #include "eirutils.h" 18 | 19 | // For size_t. 20 | #include 21 | 22 | #if defined(__linux__) 23 | #include 24 | #include 25 | #include 26 | #elif defined(_WIN32) 27 | #define WIN32_LEAN_AND_MEAN 28 | #define NOMINMAX 29 | #include 30 | #endif //CROSS PLATFORM CODE 31 | 32 | // Functions for reserving, freeing, committing and decomitting virtual memory regions. 33 | // By implementing this interface for a certain platform you enable many features of 34 | // the Eir development environment basing on very to-the-metal memory semantics! 35 | struct NativeVirtualMemoryAccessor 36 | { 37 | private: 38 | #ifdef _WIN32 39 | SYSTEM_INFO _systemInfo; 40 | #elif defined(__linux__) 41 | // Some system metrics. 42 | size_t _sys_page_size; 43 | #endif //_WIN32 44 | 45 | public: 46 | inline NativeVirtualMemoryAccessor( void ) 47 | { 48 | #ifdef _WIN32 49 | GetSystemInfo( &_systemInfo ); 50 | #elif defined(__linux__) 51 | long linux_page_size = sysconf( _SC_PAGESIZE ); 52 | 53 | FATAL_ASSERT( linux_page_size > 0 ); 54 | 55 | this->_sys_page_size = (size_t)linux_page_size; 56 | #endif //_WIN32 57 | } 58 | 59 | // As long as we do not store complicated things we are fine with default methods. 60 | inline NativeVirtualMemoryAccessor( NativeVirtualMemoryAccessor&& right ) = default; 61 | inline NativeVirtualMemoryAccessor( const NativeVirtualMemoryAccessor& right ) = default; 62 | 63 | inline NativeVirtualMemoryAccessor& operator = ( NativeVirtualMemoryAccessor&& right ) = default; 64 | inline NativeVirtualMemoryAccessor& operator = ( const NativeVirtualMemoryAccessor& right ) = default; 65 | 66 | // Platform dependent query functions. 67 | inline size_t GetPlatformPageSize( void ) const 68 | { 69 | // The page size is the amount of bytes the smallest requestable memory unit on hardware consists of. 70 | 71 | size_t page_size = 0; 72 | 73 | #ifdef _WIN32 74 | page_size = (size_t)this->_systemInfo.dwPageSize; 75 | #elif defined(__linux__) 76 | page_size = this->_sys_page_size; 77 | #else 78 | #error No page size query function for this architecture. 79 | #endif 80 | 81 | return page_size; 82 | } 83 | 84 | inline size_t GetPlatformAllocationGranularity( void ) const 85 | { 86 | // Allocation granularity defines the size of memory requestable by-minimum from the OS. 87 | // On Windows you usually cannot request memory by page-size but have to create arenas 88 | // that consist of multiple pages, managing memory inside manually. 89 | 90 | //TODO: for systems other than Windows it could make sense to specifically introduce 91 | // a recommended allocation granularity. 92 | 93 | size_t arena_size = 0; 94 | 95 | #ifdef _WIN32 96 | arena_size = (size_t)this->_systemInfo.dwAllocationGranularity; 97 | #elif defined(__linux__) 98 | // I am not aware of any limitation in the Linux kernel of this nature. 99 | arena_size = this->_sys_page_size; 100 | #else 101 | #error No memory arena query function for this architecture. 102 | #endif 103 | 104 | return arena_size; 105 | } 106 | 107 | // Cross-platform memory request API. 108 | // Allocates memory randomly or at the exactly specified position using the provided size. 109 | // The allocated memory does not have to be accessible after allocation; it could have to 110 | // be committed first. 111 | // MUST BE AN atomic operation. 112 | static inline void* RequestVirtualMemory( void *memPtr, size_t memSize ) 113 | { 114 | void *actualMemPtr = nullptr; 115 | 116 | #ifdef _WIN32 117 | actualMemPtr = VirtualAlloc( memPtr, (SIZE_T)memSize, MEM_RESERVE, PAGE_READWRITE ); 118 | #elif defined(__linux__) 119 | int mmap_flags = MAP_UNINITIALIZED|MAP_PRIVATE|MAP_ANONYMOUS; 120 | 121 | bool do_fixed = false; 122 | 123 | if ( memPtr != nullptr ) 124 | { 125 | // We must not use MAP_FIXED because it is broken shit. 126 | // Instead we must do verifications. 127 | do_fixed = true; 128 | 129 | // Under Linux 4.17 there is this new flag called MAP_FIXED_NOREPLACE. 130 | // I am happy that the Linux developers actually improve by comparison :-) 131 | mmap_flags |= MAP_FIXED_NOREPLACE; 132 | } 133 | 134 | actualMemPtr = mmap( memPtr, memSize, PROT_NONE, mmap_flags, -1, 0 ); 135 | 136 | if ( actualMemPtr == MAP_FAILED ) 137 | { 138 | return nullptr; 139 | } 140 | 141 | if ( do_fixed && actualMemPtr != memPtr ) 142 | { 143 | munmap( actualMemPtr, memSize ); 144 | return nullptr; 145 | } 146 | #endif //_WIN32 147 | 148 | return actualMemPtr; 149 | } 150 | 151 | // Release memory that was previously allocated using RequestVirtualMemory. 152 | static inline bool ReleaseVirtualMemory( void *memPtr, size_t memSize ) 153 | { 154 | bool success = false; 155 | 156 | #ifdef _WIN32 157 | // The documentation says that if we MEM_RELEASE things, the size 158 | // parameter must be 0. 159 | success = ( VirtualFree( memPtr, 0, MEM_RELEASE ) != FALSE ); 160 | #elif defined(__linux__) 161 | success = ( munmap( memPtr, memSize ) == 0 ); 162 | #endif //_WIN32 163 | 164 | FATAL_ASSERT( success == true ); 165 | 166 | return success; 167 | } 168 | 169 | // Committing and decommitting memory. 170 | // This function makes the reserved memory actually usable in the program. 171 | static inline bool CommitVirtualMemory( void *mem_ptr, size_t mem_size ) 172 | { 173 | bool success = false; 174 | 175 | #ifdef _WIN32 176 | LPVOID commitHandle = VirtualAlloc( mem_ptr, mem_size, MEM_COMMIT, PAGE_READWRITE ); 177 | 178 | success = ( commitHandle == mem_ptr ); 179 | #elif defined(__linux__) 180 | // We protect the page into accessibility. 181 | int error_out = mprotect( mem_ptr, mem_size, PROT_READ|PROT_WRITE ); 182 | 183 | success = ( error_out == 0 ); 184 | #endif //_WIN32 185 | 186 | return success; 187 | } 188 | 189 | // Decommits the memory, making it unusable by the program. 190 | static inline bool DecommitVirtualMemory( void *mem_ptr, size_t mem_size ) 191 | { 192 | bool success = false; 193 | 194 | #ifdef _WIN32 195 | BOOL decommitSuccess = VirtualFree( mem_ptr, mem_size, MEM_DECOMMIT ); 196 | 197 | success = ( decommitSuccess == TRUE ); 198 | #elif defined(__linux__) 199 | int error_out = mprotect( mem_ptr, mem_size, PROT_NONE ); 200 | 201 | success = ( error_out == 0 ); 202 | #endif //_WIN32 203 | 204 | return success; 205 | } 206 | }; 207 | 208 | #endif //_NATIVE_OS_VIRTUAL_MEMORY_FUNCS_ 209 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/OSUtils.vmemconf.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/OSUtils.vmemconf.h 6 | * PURPOSE: Virtual-memory-based vector list of structs 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _NATIVE_VIRTUAL_MEMORY_CONFIG_UTILS_ 14 | #define _NATIVE_VIRTUAL_MEMORY_CONFIG_UTILS_ 15 | 16 | #include 17 | 18 | #include "MemoryRaw.h" 19 | #include "OSUtils.vmem.h" 20 | 21 | // Shared helpers for rational memory management. 22 | struct NativeVirtualMemoryRationalConfig 23 | { 24 | static constexpr size_t RECOMMENDED_MIN_NUM_ALLOC_PAGES = 16; // We mimic the Windows operating system. 25 | static constexpr size_t RECOMMENDED_MAX_NUM_ALLOC_PAGES = 32; 26 | 27 | static constexpr size_t RECOMMENDED_STORE_ATLEAST = 3; 28 | 29 | // Returns the virtual memory size that should be reserved to support valid container commit semantics. 30 | // The function is growing monotonely on both arguments. 31 | static inline size_t GetRecommendedArenaSize( NativeVirtualMemoryAccessor& vmemAccess, size_t maintainSize, size_t structSize ) 32 | { 33 | size_t pageSize = vmemAccess.GetPlatformPageSize(); 34 | 35 | // Need to be able to at least store one entry. 36 | size_t minSizeByDef = ALIGN( maintainSize + structSize * RECOMMENDED_STORE_ATLEAST, pageSize, pageSize ); 37 | 38 | size_t minSizeBySpec = std::max( minSizeByDef, ( pageSize * RECOMMENDED_MIN_NUM_ALLOC_PAGES ) ); 39 | 40 | size_t minSizeBySystem = vmemAccess.GetPlatformAllocationGranularity(); 41 | 42 | return std::max( minSizeBySpec, minSizeBySystem ); 43 | } 44 | }; 45 | 46 | // Helper. 47 | template 48 | inline numType UINT_CEIL_DIV( numType value, numType divBy ) 49 | { 50 | if ( value == 0 ) 51 | { 52 | return 0; 53 | } 54 | 55 | // It helps to think of when the division returns exactly 1 and what 56 | // it then means to increment it by one. 57 | return ( ( value - 1 ) / divBy ) + 1; 58 | } 59 | 60 | #endif //_NATIVE_VIRTUAL_MEMORY_CONFIG_UTILS_ -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/RingBuffer.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/RingBuffer.h 6 | * PURPOSE: Ring-buffer handling helpers 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _RING_BUFFER_HANDLERS_ 14 | #define _RING_BUFFER_HANDLERS_ 15 | 16 | #include "eirutils.h" 17 | 18 | #include 19 | 20 | namespace eir 21 | { 22 | 23 | template 24 | struct RingBufferProcessor 25 | { 26 | AINLINE RingBufferProcessor( numberType iter, numberType end_iter, numberType size ) 27 | : iter( std::move( iter ) ), end_iter( std::move( end_iter ) ), size( std::move( size ) ) 28 | { 29 | return; 30 | } 31 | AINLINE RingBufferProcessor( const RingBufferProcessor& ) = default; 32 | AINLINE RingBufferProcessor( RingBufferProcessor&& ) = default; 33 | 34 | AINLINE ~RingBufferProcessor( void ) 35 | { 36 | return; 37 | } 38 | 39 | AINLINE RingBufferProcessor& operator = ( const RingBufferProcessor& ) = default; 40 | AINLINE RingBufferProcessor& operator = ( RingBufferProcessor&& ) = default; 41 | 42 | AINLINE numberType GetAvailableBytes( void ) const 43 | { 44 | numberType iter = this->iter; 45 | numberType end_iter = this->end_iter; 46 | 47 | if ( iter <= end_iter ) 48 | { 49 | return ( end_iter - iter ); 50 | } 51 | else 52 | { 53 | numberType first_left_write_count = ( size - iter ); 54 | numberType second_left_write_count = ( end_iter ); 55 | 56 | return ( first_left_write_count + second_left_write_count ); 57 | } 58 | } 59 | 60 | template 61 | AINLINE void PerformUpdate( numberType cnt, const callbackType& cb ) 62 | { 63 | numberType iter = this->iter; 64 | numberType end_iter = this->end_iter; 65 | numberType size = this->size; 66 | 67 | if ( GetAvailableBytes() < cnt ) 68 | { 69 | throw eir_exception(); 70 | } 71 | 72 | if ( iter <= end_iter ) 73 | { 74 | cb( iter, 0, cnt ); 75 | 76 | iter += cnt; 77 | 78 | if ( iter == size ) 79 | { 80 | iter = 0; 81 | } 82 | } 83 | else 84 | { 85 | numberType first_left_write_count = ( size - iter ); 86 | numberType second_left_write_count = ( end_iter ); 87 | 88 | numberType left_to_write = cnt; 89 | 90 | numberType first_write_count = std::min( cnt, first_left_write_count ); 91 | 92 | if ( first_write_count > 0 ) 93 | { 94 | cb( iter, 0, first_write_count ); 95 | 96 | iter += first_write_count; 97 | 98 | if ( iter == size ) 99 | { 100 | iter = 0; 101 | } 102 | } 103 | 104 | if ( left_to_write > first_write_count ) 105 | { 106 | left_to_write -= first_write_count; 107 | 108 | std::uint32_t second_write_count = std::min( left_to_write, second_left_write_count ); 109 | 110 | if ( second_write_count > 0 ) 111 | { 112 | cb( iter, first_write_count, second_write_count ); 113 | 114 | iter += second_write_count; 115 | } 116 | } 117 | } 118 | 119 | this->iter = iter; 120 | } 121 | 122 | AINLINE void Increment( numberType cnt ) 123 | { 124 | this->iter = ( ( this->iter + cnt ) % this->size ); 125 | } 126 | 127 | private: 128 | template 129 | AINLINE static numberType minus_modulus( numberType value, numberType subtractBy, numberType modulus ) 130 | { 131 | numberType real_subtractBy = ( subtractBy % modulus ); 132 | 133 | if ( real_subtractBy > value ) 134 | { 135 | numberType neg_value = ( real_subtractBy - value ); 136 | 137 | value = ( modulus - neg_value ); 138 | } 139 | else 140 | { 141 | value -= real_subtractBy; 142 | } 143 | 144 | return value; 145 | } 146 | 147 | public: 148 | AINLINE void Decrement( numberType cnt ) 149 | { 150 | this->iter = minus_modulus( this->iter, cnt, this->size ); 151 | } 152 | 153 | AINLINE void IncrementEnd( numberType cnt ) 154 | { 155 | this->end_iter = ( ( this->end_iter + cnt ) % this->size ); 156 | } 157 | 158 | AINLINE void DecrementEnd( numberType cnt ) 159 | { 160 | this->end_iter = minus_modulus( this->end_iter, cnt, this->size ); 161 | } 162 | 163 | AINLINE numberType GetOffset( numberType get_iter ) const 164 | { 165 | numberType iter = this->iter; 166 | numberType end_iter = this->end_iter; 167 | numberType size = this->size; 168 | 169 | if ( iter >= end_iter ) 170 | { 171 | if ( get_iter >= iter && get_iter < size ) 172 | { 173 | return ( get_iter - iter ); 174 | } 175 | 176 | if ( get_iter < end_iter ) 177 | { 178 | return ( ( size - iter ) + get_iter ); 179 | } 180 | 181 | throw eir_exception(); 182 | } 183 | else 184 | { 185 | if ( get_iter < iter || get_iter >= end_iter ) 186 | { 187 | throw eir_exception(); 188 | } 189 | 190 | return ( get_iter - iter ); 191 | } 192 | } 193 | 194 | numberType iter; 195 | numberType end_iter; 196 | numberType size; 197 | }; 198 | 199 | } //namespace eir 200 | 201 | #endif //_RING_BUFFER_HANDLERS_ -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/String.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {this->data.char_data} 5 | 6 | this->data.num_chars 7 | 8 | this->data.num_chars 9 | 0 10 | this->data.char_data 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/StringUtils.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/StringUtils.h 6 | * PURPOSE: Common string helpers 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _STRING_COMMON_SDK_UTILITIES_ 14 | #define _STRING_COMMON_SDK_UTILITIES_ 15 | 16 | #include 17 | 18 | template 19 | struct lexical_string_comparator 20 | { 21 | template 22 | AINLINE static bool is_less_than( const charType *left, const eir::String & right ) 23 | { 24 | return ( BoundedStringCompare( right.GetConstString(), right.GetLength(), left, case_sensitive ) == eir::eCompResult::LEFT_GREATER ); 25 | } 26 | 27 | template 28 | AINLINE static bool is_less_than( const eir::String & left, const charType *right ) 29 | { 30 | return ( BoundedStringCompare( left.GetConstString(), left.GetLength(), right, case_sensitive ) == eir::eCompResult::LEFT_LESS ); 31 | } 32 | 33 | template 34 | AINLINE static bool is_less_than( const eir::String & left, const eir::String & right ) 35 | { 36 | return ( FixedStringCompare( left.GetConstString(), left.GetLength(), right.GetConstString(), right.GetLength(), case_sensitive ) == eir::eCompResult::LEFT_LESS ); 37 | } 38 | }; 39 | 40 | #endif //_STRING_COMMON_SDK_UTILITIES_ -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/UniChar.casesense.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/UniChar.casesense.h 6 | * PURPOSE: Character environment case-sensitivity routines 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _UNICHAR_CASE_SENSITIVITY_ 14 | #define _UNICHAR_CASE_SENSITIVITY_ 15 | 16 | #include "MacroUtils.h" 17 | 18 | // The main reason this file got created is because std::ctype was undefined under Linux. 19 | // Hence I have to perform these things myself. 20 | 21 | template 22 | struct toupper_lookup 23 | { 24 | // NOT IMPLEMENTED. 25 | }; 26 | 27 | template 28 | struct dyna_toupper_lookup 29 | { 30 | AINLINE dyna_toupper_lookup( const std::locale& locale ) : facet( std::use_facet > ( locale ) ) 31 | { 32 | return; 33 | } 34 | 35 | AINLINE charType toupper( charType val ) const 36 | { 37 | return facet.toupper( val ); 38 | } 39 | 40 | const std::ctype & facet; 41 | }; 42 | 43 | template <> 44 | struct toupper_lookup : dyna_toupper_lookup 45 | { 46 | using dyna_toupper_lookup::dyna_toupper_lookup; 47 | }; 48 | template <> 49 | struct toupper_lookup : dyna_toupper_lookup 50 | { 51 | using dyna_toupper_lookup::dyna_toupper_lookup; 52 | }; 53 | template <> 54 | struct toupper_lookup : dyna_toupper_lookup 55 | { 56 | using dyna_toupper_lookup::dyna_toupper_lookup; 57 | }; 58 | 59 | struct utf32_wchar_toupper_lookup 60 | { 61 | AINLINE utf32_wchar_toupper_lookup( const std::locale& locale ) : _dyna_redir( locale ) 62 | { 63 | return; 64 | } 65 | 66 | AINLINE char32_t toupper( char32_t val ) const 67 | { 68 | return (char32_t)_dyna_redir.toupper( (wchar_t)val ); 69 | } 70 | 71 | dyna_toupper_lookup _dyna_redir; 72 | }; 73 | 74 | typedef std::conditional >::type char32_toupper_baseclass; 75 | 76 | template <> 77 | struct toupper_lookup : public char32_toupper_baseclass 78 | { 79 | using char32_toupper_baseclass::char32_toupper_baseclass; 80 | }; 81 | 82 | template <> 83 | struct toupper_lookup 84 | { 85 | AINLINE toupper_lookup( const std::locale& locale ) : _dyna_redir( locale ) 86 | { 87 | return; 88 | } 89 | 90 | AINLINE char8_t toupper( char8_t val ) const 91 | { 92 | return (char8_t)_dyna_redir.toupper( (char)val ); 93 | } 94 | 95 | dyna_toupper_lookup _dyna_redir; 96 | }; 97 | 98 | #endif //_UNICHAR_CASE_SENSITIVITY_ 99 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/Vector.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | this->data.data_count 6 | 7 | this->data.data_count 8 | 0 9 | this->data.data_entries 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /vendor/eirrepo/sdk/avlsetmaputil.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * PROJECT: Eir SDK 4 | * LICENSE: See LICENSE in the top level directory 5 | * FILE: eirrepo/sdk/avlsetmaputil.h 6 | * PURPOSE: Shared code between Set and Map objects 7 | * 8 | * Find the Eir SDK at: https://osdn.net/projects/eirrepo/ 9 | * Multi Theft Auto is available from http://www.multitheftauto.com/ 10 | * 11 | *****************************************************************************/ 12 | 13 | #ifndef _AVL_SET_AND_MAP_SHARED_HEADER_ 14 | #define _AVL_SET_AND_MAP_SHARED_HEADER_ 15 | 16 | #include "MacroUtils.h" 17 | #include "AVLTree.h" 18 | 19 | #define MAKE_SETMAP_ITERATOR( iteratorName, hostType, nodeType, nodeRedirNode, treeMembPath, avlTreeType ) \ 20 | struct iteratorName \ 21 | { \ 22 | AINLINE iteratorName( void ) = default; \ 23 | AINLINE iteratorName( hostType& host ) : real_iter( host.treeMembPath ) \ 24 | { \ 25 | return; \ 26 | } \ 27 | AINLINE iteratorName( hostType *host ) : real_iter( host->treeMembPath ) \ 28 | { \ 29 | return; \ 30 | } \ 31 | AINLINE iteratorName( nodeType *iter ) : real_iter( &iter->nodeRedirNode ) \ 32 | { \ 33 | return; \ 34 | } \ 35 | AINLINE iteratorName( iteratorName&& ) = default; \ 36 | AINLINE iteratorName( const iteratorName& ) = default; \ 37 | AINLINE ~iteratorName( void ) = default; \ 38 | AINLINE bool IsEnd( void ) const \ 39 | { \ 40 | return real_iter.IsEnd(); \ 41 | } \ 42 | AINLINE void Increment( void ) \ 43 | { \ 44 | real_iter.Increment(); \ 45 | } \ 46 | AINLINE nodeType* Resolve( void ) \ 47 | { \ 48 | return AVL_GETITEM( nodeType, real_iter.Resolve(), nodeRedirNode ); \ 49 | } \ 50 | private: \ 51 | typename avlTreeType::diff_node_iterator real_iter; \ 52 | } 53 | 54 | namespace eir 55 | { 56 | 57 | // Default comparator for objects inside the Map/Set. 58 | struct GenericDefaultComparator 59 | { 60 | template 61 | static AINLINE bool is_less_than( const firstKeyType& left, const secondKeyType& right ) 62 | { 63 | // We want to hide signed-ness problems, kinda. 64 | if constexpr ( std::is_integral ::value == true && std::is_integral ::value == true ) 65 | { 66 | if constexpr ( std::is_signed ::value == true && std::is_signed ::value == false ) 67 | { 68 | if ( left < 0 ) 69 | { 70 | return true; 71 | } 72 | 73 | return ( (typename std::make_unsigned ::type)left < right ); 74 | } 75 | else if constexpr ( std::is_signed ::value == false && std::is_signed ::value == true ) 76 | { 77 | if ( right < 0 ) 78 | { 79 | return false; 80 | } 81 | 82 | return ( left < (typename std::make_unsigned ::type)right ); 83 | } 84 | else 85 | { 86 | return ( left < right ); 87 | } 88 | } 89 | else 90 | { 91 | // This is important because not all key types come with a usable "operator <" overload, 92 | // for example it is not really a good idea for eir::String because you ought to take 93 | // case-sensitivity into account! 94 | return ( left < right ); 95 | } 96 | } 97 | }; 98 | 99 | } 100 | 101 | #endif //_AVL_SET_AND_MAP_SHARED_HEADER_ -------------------------------------------------------------------------------- /vendor/peframework/build/makefile: -------------------------------------------------------------------------------- 1 | CC := g++ 2 | CCFLAGS := -std=c++17 3 | srcdir := $(CURDIR)/../src 4 | objdir := $(CURDIR)/../obj/linux 5 | sources := $(shell find $(srcdir) -name "*.cpp") 6 | headers := $(shell find $(srcdir) -name "*.h") $(shell find $(srcdir) -name "*.hxx") 7 | objects := $(patsubst $(srcdir)/%,$(objdir)/%.o,$(sources)) 8 | LIBMAKE = ar 9 | INCLUDE := \ 10 | -I$(CURDIR)/../../eirrepo/ \ 11 | -I$(CURDIR)/../include/ \ 12 | 13 | main : $(objects) $(headers) ; mkdir -p ../lib/linux/ ; \ 14 | $(LIBMAKE) rcs ../lib/linux/libpeframework.a $(objects) 15 | 16 | $(objdir)/%.o : $(srcdir)/% ; \ 17 | mkdir -p $(dir $@) ; \ 18 | $(CC) $(CCFLAGS) -O3 -o $@ -c $< -Wno-invalid-offsetof $(INCLUDE) ; 19 | 20 | clean : ; \ 21 | rm -rf $(objdir) 22 | 23 | print-%: ; @echo '$*=$($*)' -------------------------------------------------------------------------------- /vendor/peframework/build/peframework.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 51 | 52 | -------------------------------------------------------------------------------- /vendor/peframework/build/peframework.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peframework", "peframework.vcxproj", "{D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Debug|x64.ActiveCfg = Debug|x64 17 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Debug|x64.Build.0 = Debug|x64 18 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Debug|x86.ActiveCfg = Debug|Win32 19 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Debug|x86.Build.0 = Debug|Win32 20 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Release|x64.ActiveCfg = Release|x64 21 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Release|x64.Build.0 = Release|x64 22 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Release|x86.ActiveCfg = Release|Win32 23 | {D9D7F4D7-423C-4DC0-AE95-A3DF0D113D05}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /vendor/peframework/build/peloader.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | this->sectionAlignment 6 | this->numSections 7 | 8 | 9 | 10 | 11 | item = (PESection*)( (char*)node - (unsigned int)&( (PESection*)0 )->sectionNode ) 12 | *item 13 | node = node->next 14 | 15 | 16 | 17 | 18 | 19 | ( {this->theSect->shortName,sb}:{this->sectOffset,x} ) 20 | 21 | -------------------------------------------------------------------------------- /vendor/peframework/include/peexcept.h: -------------------------------------------------------------------------------- 1 | #ifndef _PEFRAMEWORK_EXCEPTION_MANAGEMENT_ 2 | #define _PEFRAMEWORK_EXCEPTION_MANAGEMENT_ 3 | 4 | // Basic exception type for PEFramework. 5 | enum class ePEExceptCode 6 | { 7 | RESOURCE_ERROR, // error based on data provided by files on disk 8 | RUNTIME_ERROR, // error based on wrong assumptions of PEFramework code 9 | ACCESS_OUT_OF_BOUNDS, // error based on data access out-of-bounds (any kind) 10 | CORRUPT_PE_STRUCTURE, // error based on wrong parameters inside PE files 11 | UNSUPPORTED, // error based on not-yet-implemented features 12 | 13 | GENERIC // generic error, use when cannot be categorized 14 | }; 15 | 16 | struct peframework_exception 17 | { 18 | // Note that descString must not be malloc'ed. 19 | inline peframework_exception( ePEExceptCode code, const char *descString ) 20 | { 21 | this->codeval = code; 22 | this->what = descString; 23 | } 24 | 25 | inline ePEExceptCode code( void ) const 26 | { 27 | return this->codeval; 28 | } 29 | 30 | inline const char* desc_str( void ) const 31 | { 32 | return this->what; 33 | } 34 | 35 | private: 36 | ePEExceptCode codeval; 37 | const char *what; 38 | }; 39 | 40 | #endif //_PEFRAMEWORK_EXCEPTION_MANAGEMENT_ -------------------------------------------------------------------------------- /vendor/peframework/include/peframework.h: -------------------------------------------------------------------------------- 1 | // Main include file of PEframework. 2 | 3 | #ifndef _PEFRAMEWORK_MAIN_INCLUDE_ 4 | #define _PEFRAMEWORK_MAIN_INCLUDE_ 5 | 6 | // Basic dependencies. 7 | #include 8 | 9 | // Exception info needs first. 10 | #include "peexcept.h" 11 | 12 | // Include all modules. 13 | #include "pestream.h" 14 | #include "peloader.h" 15 | 16 | #endif //_PEFRAMEWORK_MAIN_INCLUDE_ -------------------------------------------------------------------------------- /vendor/peframework/include/peloader.common.h: -------------------------------------------------------------------------------- 1 | // PEloader common utilities that are globally included inside of the module. 2 | 3 | #ifndef _PELOADER_COMMON_HEADER_ 4 | #define _PELOADER_COMMON_HEADER_ 5 | 6 | #include "peexcept.h" 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | // Machine types. 17 | 18 | #define PEL_IMAGE_FILE_MACHINE_UNKNOWN 0 19 | #define PEL_IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. 20 | #define PEL_IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian 21 | #define PEL_IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian 22 | #define PEL_IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian 23 | #define PEL_IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2 24 | #define PEL_IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP 25 | #define PEL_IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian 26 | #define PEL_IMAGE_FILE_MACHINE_SH3DSP 0x01a3 27 | #define PEL_IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian 28 | #define PEL_IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian 29 | #define PEL_IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5 30 | #define PEL_IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian 31 | #define PEL_IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian 32 | #define PEL_IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian 33 | #define PEL_IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian 34 | #define PEL_IMAGE_FILE_MACHINE_AM33 0x01d3 35 | #define PEL_IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian 36 | #define PEL_IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 37 | #define PEL_IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64 38 | #define PEL_IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS 39 | #define PEL_IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64 40 | #define PEL_IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS 41 | #define PEL_IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS 42 | #define PEL_IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 43 | #define PEL_IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon 44 | #define PEL_IMAGE_FILE_MACHINE_CEF 0x0CEF 45 | #define PEL_IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code 46 | #define PEL_IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) 47 | #define PEL_IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian 48 | #define PEL_IMAGE_FILE_MACHINE_CEE 0xC0EE 49 | 50 | // Subsystem Values 51 | 52 | #define PEL_IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. 53 | #define PEL_IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. 54 | #define PEL_IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. 55 | #define PEL_IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. 56 | #define PEL_IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. 57 | #define PEL_IMAGE_SUBSYSTEM_POSIX_CUI 7 // image runs in the Posix character subsystem. 58 | #define PEL_IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 // image is a native Win9x driver. 59 | #define PEL_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 // Image runs in the Windows CE subsystem. 60 | #define PEL_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 // 61 | #define PEL_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 // 62 | #define PEL_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 // 63 | #define PEL_IMAGE_SUBSYSTEM_EFI_ROM 13 64 | #define PEL_IMAGE_SUBSYSTEM_XBOX 14 65 | #define PEL_IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16 66 | 67 | namespace PEloader 68 | { 69 | 70 | struct PEAllocFileAllocProxy 71 | { 72 | template 73 | AINLINE bool IsInAllocationRange( const sliceType& slice ) 74 | { 75 | // TODO: add limit checking for 32bit allocatibility here (if required). 76 | return true; 77 | } 78 | }; 79 | 80 | typedef InfiniteCollisionlessBlockAllocator peFileAlloc; 81 | 82 | struct FileSpaceAllocMan 83 | { 84 | inline FileSpaceAllocMan( void ) 85 | { 86 | return; 87 | } 88 | 89 | inline ~FileSpaceAllocMan( void ) 90 | { 91 | // Free all allocations that have not yet been freed (which is every alloc). 92 | while ( !LIST_EMPTY( this->internalAlloc.blockList.root ) ) 93 | { 94 | peFileAlloc::block_t *item = LIST_GETITEM( peFileAlloc::block_t, this->internalAlloc.blockList.root.next, node ); 95 | 96 | alloc_block_t *allocBlock = LIST_GETITEM( alloc_block_t, item, allocatorEntry ); 97 | 98 | // Remove us from registration. 99 | this->internalAlloc.RemoveBlock( item ); 100 | 101 | // Delete us. 102 | delete allocBlock; 103 | } 104 | } 105 | 106 | inline std::uint32_t AllocateAny( std::uint32_t peSize, std::uint32_t peAlignment = sizeof(std::uint32_t) ) 107 | { 108 | peFileAlloc::allocInfo alloc_data; 109 | 110 | if ( internalAlloc.FindSpace( peSize, alloc_data, peAlignment ) == false ) 111 | { 112 | throw peframework_exception( 113 | ePEExceptCode::RESOURCE_ERROR, 114 | "failed to find PE file space for allocation" 115 | ); 116 | } 117 | 118 | alloc_block_t *alloc_savior = new alloc_block_t(); 119 | 120 | internalAlloc.PutBlock( &alloc_savior->allocatorEntry, alloc_data ); 121 | 122 | return alloc_savior->allocatorEntry.slice.GetSliceStartPoint(); 123 | } 124 | 125 | inline void AllocateAt( std::uint32_t peOff, std::uint32_t peSize ) 126 | { 127 | peFileAlloc::allocInfo alloc_data; 128 | 129 | if ( internalAlloc.ObtainSpaceAt( peOff, peSize, alloc_data ) == false ) 130 | { 131 | throw peframework_exception( 132 | ePEExceptCode::RESOURCE_ERROR, 133 | "failed to obtain PE file space at presignated offset" 134 | ); 135 | } 136 | 137 | alloc_block_t *alloc_savior = new alloc_block_t(); 138 | 139 | internalAlloc.PutBlock( &alloc_savior->allocatorEntry, alloc_data ); 140 | } 141 | 142 | inline std::uint32_t GetSpanSize( std::uint32_t alignment ) 143 | { 144 | return ALIGN_SIZE( internalAlloc.GetSpanSize(), alignment ); 145 | } 146 | 147 | private: 148 | peFileAlloc internalAlloc; 149 | 150 | struct alloc_block_t 151 | { 152 | peFileAlloc::block_t allocatorEntry; 153 | }; 154 | }; 155 | 156 | }; //PEloader 157 | 158 | // Global static memory allocator. 159 | DEFINE_HEAP_ALLOC( PEGlobalStaticAllocator ); 160 | 161 | // Runtime types. 162 | template 163 | using peVector = eir::Vector ; 164 | 165 | template 166 | using peString = eir::String ; 167 | 168 | template 169 | using peMap = eir::Map ; 170 | 171 | template 172 | using peSet = eir::Set ; 173 | 174 | #endif //_PELOADER_COMMON_HEADER_ -------------------------------------------------------------------------------- /vendor/peframework/include/peloader.freg.arm.legacy.h: -------------------------------------------------------------------------------- 1 | // ARM/SH3/SH4/PowerPC (legacy stuff) implementation of function registry entries. 2 | 3 | #ifndef _PELOADER_FUNCTIONS_REGISTRY_ARM_LEGACY_ 4 | #define _PELOADER_FUNCTIONS_REGISTRY_ARM_LEGACY_ 5 | 6 | #include "peloader.h" 7 | 8 | namespace PEFileDetails 9 | { 10 | 11 | struct PERuntimeFunctionARMLegacy 12 | { 13 | PEFile::PESectionDataReference beginAddr; 14 | std::uint32_t prologLength : 8; 15 | std::uint32_t functionLength : 22; 16 | std::uint32_t is32Bit : 1; 17 | std::uint32_t hasExceptionHandler : 1; 18 | }; 19 | 20 | struct PEFunctionRegistryARMLegacy : public PEFile::PEDataDirectoryGeneric 21 | { 22 | inline PEFunctionRegistryARMLegacy( void ) = default; 23 | inline PEFunctionRegistryARMLegacy( const PEFunctionRegistryARMLegacy& ) = delete; 24 | inline PEFunctionRegistryARMLegacy( PEFunctionRegistryARMLegacy&& ) = default; 25 | 26 | void SerializeDataDirectory( PEFile::PESection *targetSect, std::uint64_t peImageBase ); 27 | 28 | peVector entries; 29 | }; 30 | 31 | } 32 | 33 | #endif //_PELOADER_FUNCTIONS_REGISTRY_ARM_LEGACY_ -------------------------------------------------------------------------------- /vendor/peframework/include/peloader.freg.arm32.h: -------------------------------------------------------------------------------- 1 | // ARM32/ARMNT implementation of runtime functions registry. 2 | 3 | #ifndef _PELOADER_FUNCTIONS_REGISTRY_ARM32_ 4 | #define _PELOADER_FUNCTIONS_REGISTRS_ARM32_ 5 | 6 | #include "peloader.h" 7 | 8 | namespace PEFileDetails 9 | { 10 | 11 | struct PERuntimeFunctionARM32 12 | { 13 | PEFile::PESectionDataReference BeginAddress; 14 | union 15 | { 16 | struct 17 | { 18 | std::uint32_t Flag : 2; 19 | std::uint32_t FunctionLength : 11; 20 | std::uint32_t Ret : 2; 21 | std::uint32_t H : 1; 22 | std::uint32_t Reg : 3; 23 | std::uint32_t R : 1; 24 | std::uint32_t L : 1; 25 | std::uint32_t C : 1; 26 | std::uint32_t StackAdjust : 10; 27 | }; 28 | std::uint32_t UnwindData; 29 | }; 30 | }; 31 | 32 | struct PEFunctionRegistryARM32 : PEFile::PEDataDirectoryGeneric 33 | { 34 | inline PEFunctionRegistryARM32( void ) = default; 35 | inline PEFunctionRegistryARM32( const PEFunctionRegistryARM32& ) = delete; 36 | inline PEFunctionRegistryARM32( PEFunctionRegistryARM32&& ) = default; 37 | 38 | void SerializeDataDirectory( PEFile::PESection *targetSect, std::uint64_t peImageBase ) override; 39 | 40 | peVector entries; 41 | }; 42 | 43 | }; 44 | 45 | #endif //_PELOADER_FUNCTIONS_REGISTRY_ARM32_ -------------------------------------------------------------------------------- /vendor/peframework/include/peloader.freg.arm64.h: -------------------------------------------------------------------------------- 1 | // ARM64 implementation of function registry entries. 2 | 3 | #ifndef _PELOADER_FUNCTIONS_REGISTRY_ARM64_ 4 | #define _PELOADER_FUNCTIONS_REGISTRY_ARM64_ 5 | 6 | #include "peloader.h" 7 | 8 | namespace PEFileDetails 9 | { 10 | 11 | struct PERuntimeFunctionARM64 12 | { 13 | PEFile::PESectionDataReference BeginAddress; 14 | union 15 | { 16 | struct 17 | { 18 | std::uint32_t flag : 2; 19 | std::uint32_t funcLen : 11; 20 | std::uint32_t regF : 3; 21 | std::uint32_t regI : 4; 22 | std::uint32_t H : 1; 23 | std::uint32_t CR : 2; 24 | std::uint32_t frameSize : 9; 25 | }; 26 | std::uint32_t UnwindData; 27 | }; 28 | }; 29 | 30 | struct PEFunctionRegistryARM64 : public PEFile::PEDataDirectoryGeneric 31 | { 32 | inline PEFunctionRegistryARM64( void ) = default; 33 | inline PEFunctionRegistryARM64( const PEFunctionRegistryARM64& ) = delete; 34 | inline PEFunctionRegistryARM64( PEFunctionRegistryARM64&& ) = default; 35 | 36 | void SerializeDataDirectory( PEFile::PESection *targetSect, std::uint64_t peImageBase ) override; 37 | 38 | peVector entries; 39 | }; 40 | 41 | }; 42 | 43 | #endif //_PELOADER_FUNCTIONS_REGISTRY_ARM64_ -------------------------------------------------------------------------------- /vendor/peframework/include/peloader.freg.h: -------------------------------------------------------------------------------- 1 | // PEFile .pdata section data structs for storing runtime function registration entries. 2 | // Due to the complexity of being divided across multiple platforms we decided to create it's own header. 3 | // Known implementations: X64, MIPS, ARM 4 | 5 | #ifndef _PELOADER_FUNCTIONS_REGISTRY_ 6 | #define _PELOADER_FUNCTIONS_REGISTRY_ 7 | 8 | namespace PEFileDetails 9 | { 10 | 11 | // TODO. 12 | 13 | }; 14 | 15 | #endif //_PELOADER_FUNCTIONS_REGISTRY_ -------------------------------------------------------------------------------- /vendor/peframework/include/peloader.freg.mips32.h: -------------------------------------------------------------------------------- 1 | // MIPS 32bit implementation of function registry entries. 2 | 3 | #ifndef _PELOADER_FUNCTIONS_REGISTRY_MIPS_ 4 | #define _PELOADER_FUNCTIONS_REGISTRY_MIPS_ 5 | 6 | #include "peloader.h" 7 | 8 | namespace PEFileDetails 9 | { 10 | 11 | struct PERuntimeFunctionMIPS 12 | { 13 | PEFile::PESectionDataReference begAddr; 14 | PEFile::PESectionDataReference endAddr; 15 | PEFile::PESectionDataReference exceptHandlerAddr; 16 | PEFile::PESectionDataReference userDataAddr; 17 | PEFile::PESectionDataReference endOfPrologAddr; 18 | }; 19 | 20 | // TODO: add the function registry and stuff. 21 | 22 | } 23 | 24 | #endif //_PELOADER_FUNCTIONS_REGISTRY_MIPS_ -------------------------------------------------------------------------------- /vendor/peframework/include/peloader.freg.x64.h: -------------------------------------------------------------------------------- 1 | // X64 and Itanium implementation of runtime functions registry. 2 | 3 | #ifndef _PELOADER_FUNCTIONS_REGISTRY_X64_ 4 | #define _PELOADER_FUNCTIONS_REGISTRY_X64_ 5 | 6 | #include "peloader.h" 7 | 8 | namespace PEFileDetails 9 | { 10 | 11 | struct PERuntimeFunctionX64 12 | { 13 | PEFile::PESectionDataReference beginAddrRef; 14 | PEFile::PESectionDataReference endAddrRef; 15 | PEFile::PESectionDataReference unwindInfoRef; 16 | }; 17 | 18 | struct PEFunctionRegistryX64 : public PEFile::PEDataDirectoryGeneric 19 | { 20 | inline PEFunctionRegistryX64( void ) = default; 21 | inline PEFunctionRegistryX64( const PEFunctionRegistryX64& ) = delete; 22 | inline PEFunctionRegistryX64( PEFunctionRegistryX64&& ) = default; 23 | 24 | void SerializeDataDirectory( PEFile::PESection *targetSect, std::uint64_t peImageBase ) override; 25 | 26 | peVector entries; 27 | }; 28 | 29 | } 30 | 31 | #endif //_PELOADER_FUNCTIONS_REGISTRY_X64_ -------------------------------------------------------------------------------- /vendor/peframework/include/peloader.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hdbeefup/dll2exe/0f882f9e32fde462fb7f4170ea02eaf5477a09e2/vendor/peframework/include/peloader.h -------------------------------------------------------------------------------- /vendor/peframework/include/pestream.h: -------------------------------------------------------------------------------- 1 | #ifndef _PEFRAMEWORK_STREAM_ 2 | #define _PEFRAMEWORK_STREAM_ 3 | 4 | // For size_t. 5 | #include 6 | 7 | #include 8 | 9 | typedef long long pe_file_ptr_t; 10 | 11 | struct PEStream abstract 12 | { 13 | virtual size_t Read( void *buf, size_t readCount ) = 0; 14 | virtual bool Write( const void *buf, size_t writeCount ) = 0; 15 | virtual bool Seek( pe_file_ptr_t ptr ) = 0; 16 | virtual pe_file_ptr_t Tell( void ) const = 0; 17 | 18 | // Helpers. 19 | template 20 | inline bool ReadStruct( structType& typeOut ) 21 | { 22 | size_t readCount = this->Read( &typeOut, sizeof(structType) ); 23 | 24 | return ( readCount == sizeof(structType) ); 25 | } 26 | 27 | template 28 | inline bool WriteStruct( const structType& typeIn ) 29 | { 30 | size_t writeCount = this->Write( &typeIn, sizeof(structType) ); 31 | 32 | return ( writeCount == sizeof(structType) ); 33 | } 34 | }; 35 | 36 | #include 37 | 38 | // Helper STL wrapper. 39 | struct PEStreamSTL : public PEStream 40 | { 41 | inline PEStreamSTL( std::iostream *implStream ) 42 | { 43 | this->implStream = implStream; 44 | } 45 | 46 | size_t Read( void *buf, size_t readCount ) override 47 | { 48 | std::iostream *stream = this->implStream; 49 | 50 | stream->read( (char*)buf, (std::streamsize)readCount ); 51 | 52 | if ( stream->bad() ) 53 | return 0; 54 | 55 | return (size_t)stream->gcount(); 56 | } 57 | 58 | bool Write( const void *buf, size_t writeCount ) override 59 | { 60 | std::iostream *stream = this->implStream; 61 | 62 | stream->write( (const char*)buf, (std::streamsize)writeCount ); 63 | 64 | return stream->good(); 65 | } 66 | 67 | pe_file_ptr_t Tell( void ) const override 68 | { 69 | return this->implStream->tellg(); // FOR FILES BOTH INPUT AND OUTPUT POINTERS ARE THE SAME BY DEFINITION. 70 | } 71 | 72 | bool Seek( pe_file_ptr_t pos ) override 73 | { 74 | std::iostream *stream = this->implStream; 75 | 76 | stream->seekg( pos ); // FOR FILES BOTH INPUT AND OUTPUT POINTERS ARE THE SAME BY DEFINITION. 77 | 78 | return stream->good(); 79 | } 80 | 81 | private: 82 | std::iostream *implStream; 83 | }; 84 | 85 | #endif //_PEFRAMEWORK_STREAM_ -------------------------------------------------------------------------------- /vendor/peframework/readme.md: -------------------------------------------------------------------------------- 1 | PEFramework is a SDK for reading, writing and executing PE files. 2 | It is meant to have no dependencies on operating systems but is 3 | developed due to the popularity of PE files on Windows. 4 | 5 | Built according to the official PE specification. 6 | Version June 2016. 7 | 8 | Dependencies: 9 | - eirrepo -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.basereloc.cpp: -------------------------------------------------------------------------------- 1 | // API specific to ease management of relocation entries in PE files. 2 | 3 | #include "peframework.h" 4 | 5 | #include "peloader.internal.hxx" 6 | 7 | void PEFile::AddRelocation( std::uint32_t rva, PEBaseReloc::eRelocType relocType ) 8 | { 9 | // We only support particular types of items here. 10 | if ( relocType != PEBaseReloc::eRelocType::ABSOLUTE && 11 | relocType != PEBaseReloc::eRelocType::HIGH && 12 | relocType != PEBaseReloc::eRelocType::LOW && 13 | relocType != PEBaseReloc::eRelocType::HIGHLOW && 14 | relocType != PEBaseReloc::eRelocType::DIR64 ) 15 | { 16 | throw peframework_exception( 17 | ePEExceptCode::RUNTIME_ERROR, 18 | "invalid relocation type registration attempt" 19 | ); 20 | } 21 | 22 | // Since we divided base relocation RVA by chunk size (default 4K) we can 23 | // simple divide to get the index by RVA aswell. Pretty nice! 24 | 25 | std::uint32_t dictIndex = ( rva / baserelocChunkSize ); 26 | 27 | PEBaseReloc& relocDict = this->baseRelocs[ dictIndex ]; 28 | 29 | // Items inside of a base relocation chunk are not structured particularily. 30 | // At least this is my assumption, based on eRelocType::HIGHADJ. 31 | 32 | std::uint32_t insideChunkOff = ( rva % baserelocChunkSize ); 33 | 34 | PEBaseReloc::item newItem; 35 | newItem.type = (std::uint16_t)relocType; 36 | newItem.offset = insideChunkOff; 37 | 38 | relocDict.items.AddToBack( std::move( newItem ) ); 39 | 40 | // We need a new base relocations array. 41 | this->baseRelocAllocEntry = PESectionAllocation(); 42 | } 43 | 44 | void PEFile::RemoveRelocations( std::uint32_t rva, std::uint32_t regionSize ) 45 | { 46 | if ( regionSize == 0 ) 47 | return; 48 | 49 | // We remove all relocations inside of the given region. 50 | 51 | std::uint32_t baserelocRemoveIndex = ( rva / baserelocChunkSize ); 52 | 53 | auto *foundMinimumNode = this->baseRelocs.FindMinimumByCriteria( 54 | [&]( const decltype(PEFile::baseRelocs)::Node *leftNode ) 55 | { 56 | std::uint32_t relocIndex = leftNode->GetKey(); 57 | 58 | if ( relocIndex < baserelocRemoveIndex ) 59 | { 60 | return eir::eCompResult::LEFT_LESS; 61 | } 62 | 63 | return eir::eCompResult::EQUAL; 64 | }); 65 | 66 | typedef sliceOfData rvaSlice_t; 67 | 68 | rvaSlice_t requestSlice( rva, regionSize ); 69 | 70 | decltype(this->baseRelocs)::iterator iter( foundMinimumNode ); 71 | 72 | while ( !iter.IsEnd() ) 73 | { 74 | decltype(this->baseRelocs)::Node *curNode = iter.Resolve(); 75 | 76 | bool doRemove = false; 77 | { 78 | PEBaseReloc& relocDict = curNode->GetValue(); 79 | 80 | // Check the relationship to this item. 81 | rvaSlice_t dictSlice( relocDict.offsetOfReloc, baserelocChunkSize ); 82 | 83 | eir::eIntersectionResult intResult = requestSlice.intersectWith( dictSlice ); 84 | 85 | if ( eir::isFloatingIntersect( intResult ) ) 86 | { 87 | // We are finished. 88 | break; 89 | } 90 | else if ( intResult == eir::INTERSECT_ENCLOSING || 91 | intResult == eir::INTERSECT_EQUAL ) 92 | { 93 | // The request is enclosing the base relocation block. 94 | // We must get rid of it entirely. 95 | doRemove = true; 96 | } 97 | else if ( intResult == eir::INTERSECT_INSIDE || 98 | intResult == eir::INTERSECT_BORDER_END || 99 | intResult == eir::INTERSECT_BORDER_START ) 100 | { 101 | // We remove single items from this base relocation entry. 102 | size_t numItems = relocDict.items.GetCount(); 103 | size_t n = 0; 104 | 105 | while ( n < numItems ) 106 | { 107 | PEBaseReloc::item& dictItem = relocDict.items[ n ]; 108 | 109 | // TODO: maybe make dict items size after what memory they actually take. 110 | 111 | rvaSlice_t itemSlice( dictSlice.GetSliceStartPoint() + dictItem.offset, 1 ); 112 | 113 | eir::eIntersectionResult itemIntResult = requestSlice.intersectWith( itemSlice ); 114 | 115 | bool shouldRemove = ( eir::isFloatingIntersect( itemIntResult ) == false ); 116 | 117 | if ( shouldRemove ) 118 | { 119 | relocDict.items.RemoveByIndex( n ); 120 | 121 | numItems--; 122 | } 123 | else 124 | { 125 | n++; 126 | } 127 | } 128 | 129 | // Now see if we can remove an empty dict. 130 | if ( numItems == 0 ) 131 | { 132 | doRemove = true; 133 | } 134 | } 135 | else 136 | { 137 | assert( 0 ); 138 | } 139 | } 140 | 141 | if ( doRemove ) 142 | { 143 | iter.Increment(); 144 | 145 | this->baseRelocs.RemoveNode( curNode ); 146 | } 147 | else 148 | { 149 | iter.Increment(); 150 | } 151 | } 152 | 153 | // Finished. 154 | } 155 | 156 | void PEFile::OnWriteAbsoluteVA( PESection *writeSect, std::uint32_t sectOff, bool is64Bit ) 157 | { 158 | // Check if we need to write a relocation entry. 159 | bool needsRelocation = false; 160 | 161 | if ( this->peOptHeader.dll_hasDynamicBase ) 162 | { 163 | needsRelocation = true; 164 | } 165 | 166 | if ( !needsRelocation ) 167 | { 168 | if ( this->baseRelocs.IsEmpty() == false ) 169 | { 170 | needsRelocation = true; 171 | } 172 | } 173 | 174 | if ( needsRelocation ) 175 | { 176 | // We either write a 32bit or 64bit relocation entry. 177 | PEBaseReloc::eRelocType relocType; 178 | 179 | if ( is64Bit ) 180 | { 181 | relocType = PEBaseReloc::eRelocType::DIR64; 182 | } 183 | else 184 | { 185 | relocType = PEBaseReloc::eRelocType::HIGHLOW; 186 | } 187 | 188 | // Calculate the RVA. 189 | std::uint32_t rva = writeSect->ResolveRVA( sectOff ); 190 | 191 | this->AddRelocation( rva, relocType ); 192 | } 193 | } 194 | 195 | bool PEFile::WriteModulePointer( PESection *writeSect, std::uint32_t sectOff, std::uint32_t targetRVA ) 196 | { 197 | std::uint64_t vaPointer = ( this->sections.GetImageBase() + targetRVA ); 198 | 199 | writeSect->stream.Seek( sectOff ); 200 | 201 | bool success; 202 | bool is64bit = this->isExtendedFormat; 203 | 204 | if ( is64bit ) 205 | { 206 | success = writeSect->stream.WriteUInt64( vaPointer ); 207 | } 208 | else 209 | { 210 | success = writeSect->stream.WriteUInt32( (std::uint32_t)( vaPointer ) ); 211 | } 212 | 213 | if ( success ) 214 | { 215 | this->OnWriteAbsoluteVA( writeSect, sectOff, is64bit ); 216 | } 217 | 218 | return success; 219 | } -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.datadirs.cpp: -------------------------------------------------------------------------------- 1 | // Generic data directory parsing manager. 2 | 3 | #include "peloader.h" 4 | 5 | #include "peloader.internal.hxx" 6 | 7 | #include "peloader.datadirs.hxx" 8 | 9 | // Include modules. 10 | extern void registerRuntimeFunctionParser( void ); 11 | 12 | extern void unregisterRuntimeFunctionParser( void ); 13 | 14 | // Now the manager implementation/initializer. 15 | struct PEDataDirectoryManager 16 | { 17 | inline PEDataDirectoryManager( void ) 18 | { 19 | // Initialize modules. 20 | registerRuntimeFunctionParser(); 21 | } 22 | 23 | inline ~PEDataDirectoryManager( void ) 24 | { 25 | // Shutdown modules. 26 | unregisterRuntimeFunctionParser(); 27 | } 28 | 29 | peMap parserMap; 30 | }; 31 | 32 | static PEDataDirectoryManager dataDirMan; 33 | 34 | void registerDataDirectoryParser( std::uint32_t idx, PEFile::PEDataDirectoryParser *parser ) 35 | { 36 | dataDirMan.parserMap[ idx ] = parser; 37 | } 38 | 39 | void unregisterDataDirectoryParser( std::uint32_t idx ) 40 | { 41 | dataDirMan.parserMap.RemoveByKey( idx ); 42 | } 43 | 44 | PEFile::PEDataDirectoryParser* findDataDirectoryParser( std::uint32_t idx ) 45 | { 46 | return ( dataDirMan.parserMap.FindOrDefault( idx ) ); 47 | } -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.datadirs.hxx: -------------------------------------------------------------------------------- 1 | // Internal header for data directory extension API. 2 | 3 | #ifndef _PELOADER_DATA_DIRECTORY_EXT_INTERNALS_ 4 | #define _PELOADER_DATA_DIRECTORY_EXT_INTERNALS_ 5 | 6 | #include "peloader.h" 7 | 8 | // These functions should be called within sub-module (de-)initializers of data directory parsers. 9 | void registerDataDirectoryParser( std::uint32_t idx, PEFile::PEDataDirectoryParser *parser ); 10 | void unregisterDataDirectoryParser( std::uint32_t idx ); 11 | PEFile::PEDataDirectoryParser* findDataDirectoryParser( std::uint32_t idx ); 12 | 13 | #endif //_PELOADER_DATA_DIRECTORY_EXT_INTERNALS_ -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.debug.cpp: -------------------------------------------------------------------------------- 1 | // PEloader helpers for dealing with the debug directory. 2 | 3 | #include "peloader.h" 4 | 5 | #include "peloader.internal.hxx" 6 | 7 | #include 8 | 9 | PEFile::PEDebugDesc& PEFile::AddDebugData( std::uint32_t debugType ) 10 | { 11 | // Create a new descriptor. 12 | { 13 | PEDebugDesc newDesc; 14 | newDesc.characteristics = 0; 15 | newDesc.timeDateStamp = (std::uint32_t)time( nullptr ); 16 | newDesc.majorVer = 0; 17 | newDesc.minorVer = 0; 18 | newDesc.type = debugType; 19 | 20 | this->debugDescs.AddToBack( std::move( newDesc ) ); 21 | 22 | // Invalidate the PE native array. 23 | this->debugDescsAlloc = PESectionAllocation(); 24 | } 25 | 26 | // Return it. 27 | return this->debugDescs.GetBack(); 28 | } 29 | 30 | bool PEFile::ClearDebugDataOfType( std::uint32_t debugType ) 31 | { 32 | bool hasChanged = false; 33 | 34 | size_t numDebugDescs = this->debugDescs.GetCount(); 35 | size_t n = 0; 36 | 37 | while ( n < numDebugDescs ) 38 | { 39 | PEDebugDesc& debugInfo = this->debugDescs[ n ]; 40 | 41 | if ( debugInfo.type == debugType ) 42 | { 43 | this->debugDescs.RemoveByIndex( n ); 44 | 45 | numDebugDescs--; 46 | 47 | hasChanged = true; 48 | } 49 | else 50 | { 51 | n++; 52 | } 53 | } 54 | 55 | if ( hasChanged ) 56 | { 57 | this->debugDescsAlloc = PESectionAllocation(); 58 | } 59 | 60 | return hasChanged; 61 | } -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.exports.cpp: -------------------------------------------------------------------------------- 1 | // Helper API for managing exports. 2 | #include "peloader.h" 3 | 4 | #include "peexcept.h" 5 | 6 | std::uint32_t PEFile::PEExportDir::AddExport( func&& entry ) 7 | { 8 | size_t currentIndex = this->functions.GetCount(); 9 | 10 | this->functions.AddToBack( std::move( entry ) ); 11 | 12 | // We need to rewrite stuff. 13 | this->allocEntry = PESectionAllocation(); 14 | this->funcAddressAllocEntry = PESectionAllocation(); 15 | 16 | return (std::uint32_t)currentIndex; 17 | } 18 | 19 | void PEFile::PEExportDir::MapName( std::uint32_t ordinal, const char *name ) 20 | { 21 | mappedName newNameMap; 22 | newNameMap.name = name; 23 | 24 | this->funcNameMap.Set( std::move( newNameMap ), std::move( ordinal ) ); 25 | 26 | // Need to recommit memory. 27 | this->allocEntry = PESectionAllocation(); 28 | this->funcNamesAllocEntry = PESectionAllocation(); 29 | } 30 | 31 | void PEFile::PEExportDir::RemoveExport( std::uint32_t ordinal ) 32 | { 33 | size_t curNumFunctions = this->functions.GetCount(); 34 | 35 | if ( ordinal >= curNumFunctions ) 36 | { 37 | throw peframework_exception( ePEExceptCode::RUNTIME_ERROR, "ordinal out of bounds for removing export" ); 38 | } 39 | 40 | // Simply reset the function field. 41 | { 42 | func& expEntry = this->functions[ ordinal ]; 43 | expEntry.isForwarder = false; 44 | expEntry.expRef = PESectionDataReference(); 45 | expEntry.forwarder.Clear(); 46 | } 47 | 48 | // Remove all name mappings of this ordinal. 49 | { 50 | auto iter = this->funcNameMap.begin(); 51 | 52 | while ( iter != this->funcNameMap.end() ) 53 | { 54 | auto *curNode = *iter; 55 | 56 | ++iter; 57 | 58 | if ( curNode->GetValue() == ordinal ) 59 | { 60 | this->funcNameMap.RemoveNode( curNode ); 61 | } 62 | } 63 | } 64 | } 65 | 66 | static inline std::uint32_t ResolveExportOrdinal( const PEFile::PEExportDir& expDir, bool isOrdinal, std::uint32_t ordinal, const peString & name, bool& hasOrdinal ) 67 | { 68 | if ( isOrdinal ) 69 | { 70 | hasOrdinal = true; 71 | // Need to subtract the ordinal base. 72 | return ( ordinal - expDir.ordinalBase ); 73 | } 74 | 75 | auto findIter = expDir.funcNameMap.Find( name ); 76 | 77 | if ( findIter != nullptr ) 78 | { 79 | hasOrdinal = true; 80 | // Internally we do not store with ordinal base offset. 81 | return (std::uint32_t)( findIter->GetValue() ); 82 | } 83 | 84 | return false; 85 | } 86 | 87 | PEFile::PEExportDir::func* PEFile::PEExportDir::ResolveExport( bool isOrdinal, std::uint32_t ordinal, const peString & name ) 88 | { 89 | bool hasImportOrdinal = false; 90 | size_t impOrdinal = ResolveExportOrdinal( *this, isOrdinal, ordinal, name, hasImportOrdinal ); 91 | 92 | if ( hasImportOrdinal && impOrdinal < this->functions.GetCount() ) 93 | { 94 | PEFile::PEExportDir::func& expFunc = this->functions[ impOrdinal ]; 95 | 96 | if ( expFunc.isForwarder == false ) 97 | { 98 | return &expFunc; 99 | } 100 | } 101 | 102 | return nullptr; 103 | } -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.imports.cpp: -------------------------------------------------------------------------------- 1 | #include "peloader.h" 2 | 3 | #include 4 | 5 | PEFile::PEImportDesc* PEFile::FindImportDescriptor( const char *moduleName ) 6 | { 7 | for ( PEImportDesc& impDesc : this->imports ) 8 | { 9 | if ( UniversalCompareStrings( 10 | moduleName, strlen(moduleName), 11 | impDesc.DLLName.GetConstString(), impDesc.DLLName.GetLength(), 12 | false 13 | ) ) 14 | { 15 | return &impDesc; 16 | } 17 | } 18 | 19 | return nullptr; 20 | } 21 | 22 | PEFile::PEImportDesc& PEFile::EstablishImportDescriptor( const char *moduleName ) 23 | { 24 | if ( PEImportDesc *impDesc = this->FindImportDescriptor( moduleName ) ) 25 | { 26 | return *impDesc; 27 | } 28 | 29 | this->imports.AddToBack( moduleName ); 30 | 31 | // Need new native array. 32 | this->importsAllocEntry = PESectionAllocation(); 33 | 34 | return this->imports.GetBack(); 35 | } 36 | 37 | const PEFile::PEImportDesc::importFunc* PEFile::PEImportDesc::FindImportEntry( std::uint16_t ordinal_hint, const char *name, bool isOrdinalImport, std::uint32_t *indexOut ) const 38 | { 39 | std::uint32_t index = 0; 40 | const PEImportDesc::importFunc *funcOut = nullptr; 41 | 42 | for ( const PEImportDesc::importFunc& impFunc : this->funcs ) 43 | { 44 | if ( isOrdinalImport ) 45 | { 46 | if ( impFunc.isOrdinalImport == true ) 47 | { 48 | if ( impFunc.ordinal_hint == ordinal_hint ) 49 | { 50 | funcOut = &impFunc; 51 | break; 52 | } 53 | } 54 | } 55 | else 56 | { 57 | if ( impFunc.isOrdinalImport == false ) 58 | { 59 | if ( impFunc.name == name ) 60 | { 61 | funcOut = &impFunc; 62 | break; 63 | } 64 | } 65 | } 66 | 67 | index++; 68 | } 69 | 70 | if ( funcOut ) 71 | { 72 | if ( indexOut ) 73 | { 74 | *indexOut = index; 75 | } 76 | } 77 | 78 | return funcOut; 79 | } 80 | 81 | PEFile::PEImportDesc::functions_t PEFile::PEImportDesc::CreateEquivalentImportsList( const functions_t& funcs ) 82 | { 83 | PEImportDesc::functions_t newFuncs; 84 | 85 | size_t modImpCount = funcs.GetCount(); 86 | 87 | for ( size_t n = 0; n < modImpCount; n++ ) 88 | { 89 | const PEFile::PEImportDesc::importFunc& impFunc = funcs[ n ]; 90 | 91 | PEFile::PEImportDesc::importFunc carbonCopy; 92 | carbonCopy.isOrdinalImport = impFunc.isOrdinalImport; 93 | carbonCopy.name = impFunc.name; 94 | carbonCopy.nameAllocEntry = impFunc.nameAllocEntry.CloneOnlyFinal(); 95 | carbonCopy.ordinal_hint = impFunc.ordinal_hint; 96 | 97 | newFuncs.AddToBack( std::move( carbonCopy ) ); 98 | } 99 | 100 | return newFuncs; 101 | } -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.internal.hxx: -------------------------------------------------------------------------------- 1 | #ifndef _PELOADER_INTERNAL_ 2 | #define _PELOADER_INTERNAL_ 3 | 4 | // Forward to the global header, because it is sometimes necessary. 5 | #include "peloader.serialize.h" 6 | 7 | // Helper function for pointer size. 8 | inline std::uint32_t GetPEPointerSize( bool isExtendedFormat ) 9 | { 10 | if ( isExtendedFormat ) 11 | { 12 | return sizeof(std::uint64_t); 13 | } 14 | 15 | return sizeof(std::uint32_t); 16 | } 17 | 18 | static AINLINE std::uint32_t VA2RVA( std::uint64_t va, std::uint64_t imageBase ) 19 | { 20 | if ( va == 0 ) 21 | return 0; 22 | 23 | return (std::uint32_t)( va - imageBase ); 24 | } 25 | 26 | #endif //_PELOADER_INTERNAL_ -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.memory.cpp: -------------------------------------------------------------------------------- 1 | // Memory management header of peframework. 2 | // We must not initialize any static memory here but we can redirect to third-party libraries. 3 | #include "peloader.h" 4 | 5 | #ifdef PEFRAMEWORK_NATIVE_EXECUTIVE 6 | #include 7 | #endif //PEFRAMEWORK_NATIVE_EXECUTIVE 8 | 9 | void* PEGlobalStaticAllocator::Allocate( void *refPtr, size_t memSize, size_t alignment ) 10 | { 11 | #ifdef PEFRAMEWORK_NATIVE_EXECUTIVE 12 | return NatExecGlobalStaticAlloc::Allocate( refPtr, memSize, alignment ); 13 | #else 14 | return CRTHeapAllocator::Allocate( refPtr, memSize, alignment ); 15 | #endif //PEFRAMEWORK_NATIVE_EXECUTIVE 16 | } 17 | 18 | bool PEGlobalStaticAllocator::Resize( void *refPtr, void *memPtr, size_t memSize ) 19 | { 20 | #ifdef PEFRAMEWORK_NATIVE_EXECUTIVE 21 | return NatExecGlobalStaticAlloc::Resize( refPtr, memPtr, memSize ); 22 | #else 23 | return CRTHeapAllocator::Resize( refPtr, memPtr, memSize ); 24 | #endif //PEFRAMEWORK_NATIVE_EXECUTIVE 25 | } 26 | 27 | void PEGlobalStaticAllocator::Free( void *refPtr, void *memPtr ) 28 | { 29 | #ifdef PEFRAMEWORK_NATIVE_EXECUTIVE 30 | NatExecGlobalStaticAlloc::Free( refPtr, memPtr ); 31 | #else 32 | CRTHeapAllocator::Free( refPtr, memPtr ); 33 | #endif //PEFRAMRWORK_NATIVE_EXECUTIVE 34 | } -------------------------------------------------------------------------------- /vendor/peframework/src/peloader.resource.cpp: -------------------------------------------------------------------------------- 1 | // Resource helper API. 2 | #include "peloader.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | // Generic finder routine. 9 | PEFile::PEResourceItem* PEFile::PEResourceDir::FindItem( bool isIdentifierName, const peString & name, std::uint16_t identifier ) 10 | { 11 | if ( isIdentifierName ) 12 | { 13 | auto *findIter = this->idChildren.Find( identifier ); 14 | 15 | if ( findIter != nullptr ) 16 | { 17 | return findIter->GetValue(); 18 | } 19 | } 20 | else 21 | { 22 | auto *findIter = this->namedChildren.Find( name ); 23 | 24 | if ( findIter != nullptr ) 25 | { 26 | return findIter->GetValue(); 27 | } 28 | } 29 | 30 | return nullptr; 31 | } 32 | 33 | peString PEFile::PEResourceItem::GetName( void ) const 34 | { 35 | if ( !this->hasIdentifierName ) 36 | { 37 | return CharacterUtil::ConvertStrings ( this->name ); 38 | } 39 | else 40 | { 41 | peString charBuild( L"(ident:" ); 42 | 43 | charBuild += eir::to_string ( this->identifier ); 44 | 45 | charBuild += L")"; 46 | 47 | return charBuild; 48 | } 49 | } 50 | 51 | bool PEFile::PEResourceDir::AddItem( PEFile::PEResourceItem *theItem ) 52 | { 53 | if ( theItem->hasIdentifierName ) 54 | { 55 | this->idChildren.Insert( theItem ); 56 | } 57 | else 58 | { 59 | this->namedChildren.Insert( theItem ); 60 | } 61 | 62 | return true; 63 | } 64 | 65 | bool PEFile::PEResourceDir::RemoveItem( const PEFile::PEResourceItem *theItem ) 66 | { 67 | if ( theItem->hasIdentifierName ) 68 | { 69 | auto *findIter = this->idChildren.Find( theItem ); 70 | 71 | if ( findIter != nullptr ) 72 | { 73 | this->idChildren.RemoveNode( findIter ); 74 | 75 | return true; 76 | } 77 | } 78 | else 79 | { 80 | auto *findIter = this->namedChildren.Find( theItem ); 81 | 82 | if ( findIter != nullptr ) 83 | { 84 | this->namedChildren.RemoveNode( findIter ); 85 | 86 | return true; 87 | } 88 | } 89 | 90 | return false; 91 | } 92 | 93 | PEFile::PEResourceInfo* PEFile::PEResourceDir::PutData( bool isIdentifierName, peString name, std::uint16_t identifier, PESectionDataReference dataRef ) 94 | { 95 | PEResourceItem *existingItem = this->FindItem( isIdentifierName, name, identifier ); 96 | 97 | if ( existingItem ) 98 | { 99 | if ( existingItem->itemType == eType::DATA ) 100 | { 101 | PEResourceInfo *dataItem = (PEResourceInfo*)existingItem; 102 | 103 | // Update the item. 104 | dataItem->sectRef = std::move( dataRef ); 105 | return dataItem; 106 | } 107 | } 108 | 109 | PEResourceInfo *newItem = CreateData( isIdentifierName, std::move( name ), std::move( identifier ), std::move( dataRef ) ); 110 | 111 | if ( newItem ) 112 | { 113 | if ( existingItem ) 114 | { 115 | this->RemoveItem( existingItem ); 116 | 117 | // We also delete the item. 118 | DestroyItem( existingItem ); 119 | } 120 | 121 | this->AddItem( newItem ); 122 | } 123 | 124 | return newItem; 125 | } 126 | 127 | PEFile::PEResourceDir* PEFile::PEResourceDir::MakeDir( bool isIdentifierName, peString name, std::uint16_t identifier ) 128 | { 129 | PEResourceItem *existingItem = this->FindItem( isIdentifierName, name, identifier ); 130 | 131 | if ( existingItem ) 132 | { 133 | if ( existingItem->itemType == eType::DIRECTORY ) 134 | { 135 | PEResourceDir *dirItem = (PEResourceDir*)existingItem; 136 | 137 | return dirItem; 138 | } 139 | } 140 | 141 | PEResourceDir *newItem = CreateDir( isIdentifierName, std::move( name ), std::move( identifier ) ); 142 | 143 | if ( newItem ) 144 | { 145 | if ( existingItem ) 146 | { 147 | this->RemoveItem( existingItem ); 148 | 149 | // We also destroy the item. 150 | DestroyItem( existingItem ); 151 | } 152 | 153 | this->AddItem( newItem ); 154 | } 155 | 156 | return newItem; 157 | } --------------------------------------------------------------------------------