├── .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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
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 | }
--------------------------------------------------------------------------------