working buildsystem; still cannot open PE32+ binaries with zipr
This commit is contained in:
		
							parent
							
								
									30ea9163c9
								
							
						
					
					
						commit
						3f1cf080f2
					
				
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,6 +1,11 @@ | |||||||
| *.o | *.o | ||||||
| *.so | *.so | ||||||
| *.a | *.a | ||||||
|  | *.test | ||||||
| 
 | 
 | ||||||
|  | build/ | ||||||
| plugins_install/ | plugins_install/ | ||||||
|  | 
 | ||||||
| .sconsign.dblite | .sconsign.dblite | ||||||
|  | 
 | ||||||
|  | peasoup_executable*/ | ||||||
|  | |||||||
							
								
								
									
										36
									
								
								SConscript
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								SConscript
									
									
									
									
									
								
							| @ -1,36 +0,0 @@ | |||||||
| import os |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # import the environment and clone it so we can make changes. |  | ||||||
| # |  | ||||||
| Import('env') |  | ||||||
| irdb_env = env.Clone() |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # These settings are recommended, but you can choose what you like |  | ||||||
| # |  | ||||||
| # be strict about syntax/warnings |  | ||||||
| irdb_env.Append(CXXFLAGS=" -Wall -Werror -fmax-errors=2 ") |  | ||||||
| # link against core and transform libraries |  | ||||||
| irdb_env.Append(LIBS=Split("irdb-core irdb-transform")) |  | ||||||
| # be able to include the SDK files |  | ||||||
| irdb_env.Append(CPPPATH=" $IRDB_SDK/include ") |  | ||||||
| # this is where the libraries are. |  | ||||||
| irdb_env.Append(LIBPATH=Split(" $IRDB_LIBS ")) |  | ||||||
| # this is where to place plugins. |  | ||||||
| irdb_env.Replace(INSTALL_PATH=os.environ['PWD']+"/plugins_install") |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # export the new environment for children sub-conscripts |  | ||||||
| # |  | ||||||
| Export('irdb_env') |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # include the children sconscript files. |  | ||||||
| # |  | ||||||
| libs = irdb_env.SConscript("./transforms/SConscript") |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # And we are done |  | ||||||
| # |  | ||||||
| Return('libs') |  | ||||||
							
								
								
									
										33
									
								
								SConstruct
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								SConstruct
									
									
									
									
									
								
							| @ -1,33 +0,0 @@ | |||||||
| import os |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| env = Environment() |  | ||||||
| 
 |  | ||||||
| pwd = os.getcwd() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| env.Replace(TRANSFORMS_HOME=os.path.join(pwd, "transforms")) |  | ||||||
| env.Replace(IRDB_SDK=os.path.join(pwd, "irdb-sdk")) |  | ||||||
| env.Replace(IRDB_LIBS=os.environ['IRDB_LIBS']) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| env.Replace(debug=ARGUMENTS.get("debug", 0)) |  | ||||||
| 
 |  | ||||||
| env.Append(CXXFLAGS=" -std=c++11 ") |  | ||||||
| env.Append(LINKFLAGS=" -Wl,-unresolved-symbols=ignore-in-shared-libs ") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if int(env['debug']) == 1: |  | ||||||
|     env.Append(CFLAGS=" -g ") |  | ||||||
|     env.Append(CXXFLAGS=" -g ") |  | ||||||
|     env.Append(LINKFLAGS=" -g ") |  | ||||||
|     env.Append(SHLINKFLAGS=" -g ") |  | ||||||
| else: |  | ||||||
|     env.Append(CFLAGS=" -O ") |  | ||||||
|     env.Append(CXXFLAGS=" -O ") |  | ||||||
|     env.Append(LINKFLAGS=" -O ") |  | ||||||
|     env.Append(SHLINKFLAGS=" -O ") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| Export('env') |  | ||||||
| SConscript("SConscript", variant_dir='build') |  | ||||||
| @ -1,36 +0,0 @@ | |||||||
| import os |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # import the environment and clone it so we can make changes. |  | ||||||
| # |  | ||||||
| Import('env') |  | ||||||
| irdb_env = env.Clone() |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # These settings are recommended, but you can choose what you like |  | ||||||
| # |  | ||||||
| # be strict about syntax/warnings |  | ||||||
| irdb_env.Append(CXXFLAGS=" -Wall -Werror -fmax-errors=2 ") |  | ||||||
| # link against core and transform libraries |  | ||||||
| irdb_env.Append(LIBS=Split("irdb-core irdb-transform")) |  | ||||||
| # be able to include the SDK files |  | ||||||
| irdb_env.Append(CPPPATH=" $IRDB_SDK/include ") |  | ||||||
| # this is where the libraries are. |  | ||||||
| irdb_env.Append(LIBPATH=Split(" $IRDB_LIBS ")) |  | ||||||
| # this is where to place plugins. |  | ||||||
| irdb_env.Replace(INSTALL_PATH=os.environ['PWD']+"/plugins_install") |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # export the new environment for children sub-conscripts |  | ||||||
| # |  | ||||||
| Export('irdb_env') |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # include the children sconscript files. |  | ||||||
| # |  | ||||||
| libs = irdb_env.SConscript("./transforms/SConscript") |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # And we are done |  | ||||||
| # |  | ||||||
| Return('libs') |  | ||||||
| @ -1,23 +0,0 @@ | |||||||
| # import and create a copy of the environment so we don't change |  | ||||||
| # anyone else's env. |  | ||||||
| Import('irdb_env') |  | ||||||
| myenv = irdb_env.Clone() |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # set input files and output program name |  | ||||||
| # |  | ||||||
| files = Glob(Dir('.').srcnode().abspath+"/*.cpp") |  | ||||||
| pgm_name = "initialize_stack.exe" |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # build, install and return the program by default. |  | ||||||
| # |  | ||||||
| pgm = irdb_env.Program(pgm_name,  files) |  | ||||||
| install = myenv.Install("$INSTALL_PATH/", pgm) |  | ||||||
| Default(install) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # and we're done |  | ||||||
| # |  | ||||||
| Return('install') |  | ||||||
										
											Binary file not shown.
										
									
								
							| @ -1,3 +1,7 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
| 
 | 
 | ||||||
| podman run --rm -it -v $(pwd):/work:z -w /work git.zephyr-software.com:4567/opensrc/zipr/zipr-bin iagree | sudo chmod -R 777 transforms/ | ||||||
|  | podman run --rm -it -v $(pwd):/work:Z -w /work git.zephyr-software.com:4567/opensrc/zipr/zipr-bin iagree | ||||||
|  | 
 | ||||||
|  | # ./do-build | ||||||
|  | # pszr programs/compiled/JustOpen.exe JustOpen.test | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								do-build
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										145
									
								
								do-build
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,145 @@ | |||||||
|  | #!/bin/env python3 | ||||||
|  | 
 | ||||||
|  | import os | ||||||
|  | import hashlib | ||||||
|  | import base64 | ||||||
|  | import argparse | ||||||
|  | 
 | ||||||
|  | DIR = os.path.dirname(os.path.realpath(__file__)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def parse_args(): | ||||||
|  |     parser = argparse.ArgumentParser() | ||||||
|  |     parser.add_argument('--force', action='store_true') | ||||||
|  |     return parser.parse_args() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | args = parse_args() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | CXX = "g++" | ||||||
|  | LDFLAGS = "-Wl,-unresolved-symbols=ignore-in-shared-libs -L/opt/ps_zipr/irdb-libs/lib" | ||||||
|  | CXXFLAGS = f"-g -I{DIR}/irdb-sdk/include -std=c++11 -Wall -Werror -fmax-errors=2 -fPIC" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def list_hash(list: list[str]): | ||||||
|  |     md5 = hashlib.md5() | ||||||
|  |     for item in list: | ||||||
|  |         md5.update(item.encode()) | ||||||
|  | 
 | ||||||
|  |     return md5.hexdigest() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def file_hash(file: str): | ||||||
|  |     BUFSIZE = 65536 | ||||||
|  | 
 | ||||||
|  |     md5 = hashlib.md5() | ||||||
|  | 
 | ||||||
|  |     with open(file, 'rb') as f: | ||||||
|  |         data = f.read(BUFSIZE) | ||||||
|  |         while data: | ||||||
|  |             md5.update(data) | ||||||
|  |             data = f.read(BUFSIZE) | ||||||
|  | 
 | ||||||
|  |     return md5.hexdigest() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def needs_rebuild(file: str, libs: list[str] = []) -> bool: | ||||||
|  |     return True | ||||||
|  |     global args | ||||||
|  | 
 | ||||||
|  |     hash = file_hash(file) | ||||||
|  |     hash += list_hash(libs) | ||||||
|  | 
 | ||||||
|  |     abspath = os.path.abspath(file) | ||||||
|  |     b64path = os.path.join('/tmp', base64.b64encode(abspath.encode()).decode()) | ||||||
|  | 
 | ||||||
|  |     if not os.path.exists(b64path) or args.force: | ||||||
|  |         return True | ||||||
|  | 
 | ||||||
|  |     with open(b64path, 'r') as f: | ||||||
|  |         return f.read() != hash | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def signal_built(file: str, libs: list[str] = []) -> bool: | ||||||
|  |     return | ||||||
|  |     hash = file_hash(file) | ||||||
|  |     hash += list_hash(libs) | ||||||
|  | 
 | ||||||
|  |     abspath = os.path.abspath(file) | ||||||
|  |     b64path = os.path.join('/tmp', base64.b64encode(abspath.encode()).decode()) | ||||||
|  | 
 | ||||||
|  |     with open(b64path, 'w') as f: | ||||||
|  |         f.write(hash) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def build(targetObject: str, cppFile: str): | ||||||
|  |     if not needs_rebuild(cppFile): | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |     global CXXFLAGS | ||||||
|  | 
 | ||||||
|  |     cmd = f'{CXX} -c "{cppFile}" -o "{targetObject}" {CXXFLAGS}' | ||||||
|  |     print(cmd) | ||||||
|  |     status = os.system(cmd) | ||||||
|  | 
 | ||||||
|  |     if status == 0: | ||||||
|  |         signal_built(cppFile) | ||||||
|  |         return True | ||||||
|  | 
 | ||||||
|  |     return False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def link(target: str, objects: list[str], libs: list[str]): | ||||||
|  |     global LDFLAGS | ||||||
|  | 
 | ||||||
|  |     cmd = f'{CXX} -shared -o {target}' | ||||||
|  |     for object in objects: | ||||||
|  |         cmd += f' {object}' | ||||||
|  |     for lib in libs: | ||||||
|  |         cmd += f' -l{lib}' | ||||||
|  |     cmd += f' {LDFLAGS}' | ||||||
|  | 
 | ||||||
|  |     print(cmd) | ||||||
|  |     return os.system(cmd) == 0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def main(): | ||||||
|  |     for dir in os.listdir(f'{DIR}/transforms'): | ||||||
|  |         path = os.path.join(f'{DIR}/transforms', dir) | ||||||
|  |         if not os.path.isdir(path): | ||||||
|  |             continue | ||||||
|  | 
 | ||||||
|  |         libs: list[str] = [] | ||||||
|  |         if os.path.exists(os.path.join(path, '.libs')): | ||||||
|  |             with open(os.path.join(path, '.libs'), 'r') as f: | ||||||
|  |                 libs = f.read().split() | ||||||
|  | 
 | ||||||
|  |             libs = filter(lambda l: len(l.strip()) > 0, libs) | ||||||
|  |             libs = list(libs) | ||||||
|  | 
 | ||||||
|  |         hadError = False | ||||||
|  |         objects: list[str] = [] | ||||||
|  |         for file in os.listdir(path): | ||||||
|  |             if not file.endswith('.cpp'): | ||||||
|  |                 continue | ||||||
|  | 
 | ||||||
|  |             filePath = os.path.join(path, file) | ||||||
|  | 
 | ||||||
|  |             objectPath = os.path.splitext(filePath)[0] + '.o' | ||||||
|  |             newError = not build(objectPath, filePath) | ||||||
|  |             hadError = hadError or newError | ||||||
|  |             objects += [objectPath] | ||||||
|  | 
 | ||||||
|  |         if hadError: | ||||||
|  |             continue | ||||||
|  | 
 | ||||||
|  |         targetDir = os.path.join(DIR, 'plugins_install') | ||||||
|  |         os.makedirs(targetDir, exist_ok=True) | ||||||
|  | 
 | ||||||
|  |         target = os.path.join(targetDir, f'lib{dir}.so') | ||||||
|  |         link(target, objects, libs) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     main() | ||||||
							
								
								
									
										
											BIN
										
									
								
								programs/compiled/JustOpen.exe
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								programs/compiled/JustOpen.exe
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										22
									
								
								programs/source/JustOpen.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								programs/source/JustOpen.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | #include <windows.h> | ||||||
|  | #include <commdlg.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | int main() { | ||||||
|  |     char file[MAX_PATH] = {0}; | ||||||
|  |      | ||||||
|  |     OPENFILENAME ofn = { | ||||||
|  |         .lStructSize = sizeof(ofn), | ||||||
|  |         .lpstrFilter = "All Files\0*.*\0", | ||||||
|  |         .lpstrFile = file, | ||||||
|  |         .nMaxFile = MAX_PATH, | ||||||
|  |         .lpstrTitle = "Select File", | ||||||
|  |         .Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     int res = GetOpenFileName(&ofn); | ||||||
|  | 
 | ||||||
|  |     if (res) printf("%s\n", file); | ||||||
|  | 
 | ||||||
|  |     return res != 0; | ||||||
|  | } | ||||||
| @ -1 +1 @@ | |||||||
| export PSPATH=$PSPATH:$TRANSFORMS_HOME/plugins_install | export PSPATH=$PSPATH:$(pwd)/plugins_install | ||||||
|  | |||||||
| @ -1,23 +0,0 @@ | |||||||
| # import and create a copy of the environment so we don't change |  | ||||||
| # anyone else's env. |  | ||||||
| Import('irdb_env') |  | ||||||
| myenv = irdb_env.Clone() |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # set input files and output program name |  | ||||||
| # |  | ||||||
| files = Glob(Dir('.').srcnode().abspath+"/*.cpp") |  | ||||||
| pgm_name = "initialize_stack.exe" |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # build, install and return the program by default. |  | ||||||
| # |  | ||||||
| pgm = irdb_env.Program(pgm_name,  files) |  | ||||||
| install = myenv.Install("$INSTALL_PATH/", pgm) |  | ||||||
| Default(install) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| # |  | ||||||
| # and we're done |  | ||||||
| # |  | ||||||
| Return('install') |  | ||||||
							
								
								
									
										1
									
								
								transforms/forward_file_open/.libs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								transforms/forward_file_open/.libs
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | irdb-core irdb-transform | ||||||
							
								
								
									
										23
									
								
								transforms/forward_file_open/driver.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								transforms/forward_file_open/driver.cpp
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | #include "irdb-core" | ||||||
|  | #include "logic.hpp" | ||||||
|  | #include <memory> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | class ForwardFileOpenDriver : public TransformStep_t { | ||||||
|  | public: | ||||||
|  |   int parseArgs(const vector<string> args) override { return 0; } | ||||||
|  | 
 | ||||||
|  |   int executeStep() override { | ||||||
|  |     auto firp = getMainFileIR(); | ||||||
|  |     auto success = ForwardFileOpen(firp).execute(); | ||||||
|  |     return success ? 0 : 2; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   string getStepName() const override { return "forward_file_open"; } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | extern "C" shared_ptr<TransformStep_t> getTransformStep(void) { | ||||||
|  |   return shared_ptr<TransformStep_t>(new ForwardFileOpenDriver()); | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								transforms/forward_file_open/logic.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								transforms/forward_file_open/logic.cpp
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | #include "logic.hpp" | ||||||
|  | #include "irdb-transform" | ||||||
|  | 
 | ||||||
|  | ForwardFileOpen::ForwardFileOpen(FileIR_t *p_variantIR) | ||||||
|  |     : Transform_t(p_variantIR) {} | ||||||
|  | 
 | ||||||
|  | bool ForwardFileOpen::execute() { | ||||||
|  |   const auto insts = getFileIR()->getInstructions(); | ||||||
|  | 
 | ||||||
|  |   cout << "Hello World!" << std::endl; | ||||||
|  | 
 | ||||||
|  |   for (auto &inst : insts) { | ||||||
|  |     cout << inst->getDisassembly() << std::endl; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return true; | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								transforms/forward_file_open/logic.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								transforms/forward_file_open/logic.hpp
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <irdb-core> | ||||||
|  | #include <irdb-deep> | ||||||
|  | #include <irdb-transform> | ||||||
|  | 
 | ||||||
|  | #include <iostream> | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | using namespace std; | ||||||
|  | using namespace IRDB_SDK; | ||||||
|  | 
 | ||||||
|  | class ForwardFileOpen : protected Transform_t { | ||||||
|  | public: | ||||||
|  |   ForwardFileOpen(FileIR_t *p_variantIR); | ||||||
|  |   bool execute(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | }; | ||||||
| @ -1,147 +0,0 @@ | |||||||
| #include "initialize_stack.hpp" |  | ||||||
| #include <algorithm> |  | ||||||
| #include <fstream> |  | ||||||
| #include <math.h> |  | ||||||
| 
 |  | ||||||
| #define ALLOF(a) begin(a), end(a) |  | ||||||
| 
 |  | ||||||
| using namespace std; |  | ||||||
| using namespace IRDB_SDK; |  | ||||||
| using namespace InitStack; |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // constructor
 |  | ||||||
| //
 |  | ||||||
| InitStack_t::InitStack_t(FileIR_t *p_variantIR, |  | ||||||
|                          const string &p_functions_filename, int p_init_value, |  | ||||||
|                          bool p_verbose) |  | ||||||
|     : Transform_t(p_variantIR), // initialize the Transform class so things like
 |  | ||||||
|                                 // insertAssembly and getFileIR() can be used
 |  | ||||||
|       m_init_value(p_init_value), // member variable inits, these will vary
 |  | ||||||
|                                   // depending on your transform's objectives
 |  | ||||||
|       m_verbose(p_verbose), m_num_transformed(0) { |  | ||||||
|   // check whether to read in a list of functions to transform
 |  | ||||||
|   if (p_functions_filename == "") { |  | ||||||
|     cout << "Auto-initialize all functions" << endl; |  | ||||||
|     m_funcs_to_init = |  | ||||||
|         getFileIR()->getFunctions(); // use all functions from the IR
 |  | ||||||
|   } else { |  | ||||||
|     cout << "Auto-initialize functions specified in: " << p_functions_filename |  | ||||||
|          << endl; |  | ||||||
|     readFunctionsFromFile(p_functions_filename); // read functions from file
 |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // read list of functions to auto-initialize
 |  | ||||||
| //
 |  | ||||||
| // post conditions: set of functions to auto-initialize
 |  | ||||||
| //
 |  | ||||||
| void InitStack_t::readFunctionsFromFile(const string &p_filename) { |  | ||||||
|   // get all functions for readability of the rest of the code
 |  | ||||||
|   const auto &all_funcs = getFileIR()->getFunctions(); |  | ||||||
| 
 |  | ||||||
|   // open input file and check for successful open
 |  | ||||||
|   ifstream functionsFile( |  | ||||||
|       p_filename); // can't use auto decl here because of lack of copy
 |  | ||||||
|                    // constructor in ifstream class
 |  | ||||||
|   if (!functionsFile.is_open()) |  | ||||||
|     throw runtime_error("Cannot open " + p_filename); |  | ||||||
| 
 |  | ||||||
|   // read each line of the input file.
 |  | ||||||
|   auto line = string(); |  | ||||||
|   while (functionsFile >> line) { |  | ||||||
|     // locate a function with the name read from the file.
 |  | ||||||
|     const auto func_it = find_if(ALLOF(all_funcs), [&](const Function_t *f) { |  | ||||||
|       return f->getName() == line; |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     // if found, log and insert it into the set to transform
 |  | ||||||
|     if (func_it != end(all_funcs)) { |  | ||||||
|       auto f = *func_it; |  | ||||||
|       cout << "Adding " << f->getName() << " to function list" << endl; |  | ||||||
|       m_funcs_to_init.insert(f); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // Execute the transform by transforming all to-transform functions
 |  | ||||||
| //
 |  | ||||||
| // preconditions: the FileIR is read as from the IRDB. valid file listing
 |  | ||||||
| // functions to auto-initialize postcondition: instructions added to
 |  | ||||||
| // auto-initialize stack for each specified function
 |  | ||||||
| //
 |  | ||||||
| //
 |  | ||||||
| bool InitStack_t::execute() { |  | ||||||
|   // transform all functions
 |  | ||||||
|   for (auto f : m_funcs_to_init) |  | ||||||
|     initStack(f); |  | ||||||
| 
 |  | ||||||
|   // #ATTRIBUTE is a convention used to help find useful information in log
 |  | ||||||
|   // files
 |  | ||||||
|   cout << "#ATTRIBUTE InitStack::num_transformed=" << m_num_transformed << endl; |  | ||||||
| 
 |  | ||||||
|   return m_num_transformed > 0; // true means success
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // preconditions : f is not NULL
 |  | ||||||
| // postconditions: stack auto-initialized if stack frame size > 0
 |  | ||||||
| //
 |  | ||||||
| void InitStack_t::initStack(Function_t *f) { |  | ||||||
|   // preconditions
 |  | ||||||
|   assert(f != nullptr); |  | ||||||
| 
 |  | ||||||
|   // check that the frame size is in the area we care about
 |  | ||||||
|   const auto frame_size = f->getStackFrameSize(); |  | ||||||
| 
 |  | ||||||
|   // nothing to init.
 |  | ||||||
|   if (frame_size == 0) |  | ||||||
|     return; |  | ||||||
| 
 |  | ||||||
|   const auto num_locs = static_cast<uint64_t>(ceil(frame_size / 4.0)); |  | ||||||
| 
 |  | ||||||
|   // debug output
 |  | ||||||
|   cout << "Function: " << f->getName() |  | ||||||
|        << " frame size: " << f->getStackFrameSize() << endl; |  | ||||||
| 
 |  | ||||||
|   // not all functions have an entry point
 |  | ||||||
|   const auto entry = f->getEntryPoint(); |  | ||||||
|   if (!entry) |  | ||||||
|     return; |  | ||||||
| 
 |  | ||||||
|   // log what we are doing
 |  | ||||||
|   cout << "Function: " << f->getName() << " auto-initialize " << dec << num_locs |  | ||||||
|        << "  stack memory locations (4 bytes at a time) with value = " << hex |  | ||||||
|        << m_init_value << endl; |  | ||||||
| 
 |  | ||||||
|   // determine the registers to use on x86-32 or  x86-64
 |  | ||||||
|   const auto sp_reg = |  | ||||||
|       getFileIR()->getArchitectureBitWidth() == 64 ? "rsp" : "esp"; |  | ||||||
|   const auto scratch_reg = |  | ||||||
|       getFileIR()->getArchitectureBitWidth() == 64 ? "r11" : "ecx"; |  | ||||||
| 
 |  | ||||||
|   // Now, do the dirty work of inserting new assembly to initialize the stack.
 |  | ||||||
|   // Insert these instructions at the start of the function (to initialize the
 |  | ||||||
|   // stack frame before the function runs) Assume: flags are dead at function
 |  | ||||||
|   // entry. Future work: Verify this is true using dead register list. Note: we
 |  | ||||||
|   // spill a scratch register into the red zone at 120 bytes passed the end of
 |  | ||||||
|   // the frame
 |  | ||||||
| 
 |  | ||||||
|   const auto newInsns = insertAssemblyInstructionsBefore( |  | ||||||
|       entry, |  | ||||||
|       string() + "    mov [%%1 + %%2], %%3\n" |  | ||||||
|                  "    mov %%3, -%%4\n" |  | ||||||
|                  "L1: mov dword [%%1 + %%3 * 4 - 4], %%5\n" |  | ||||||
|                  "    inc %%3\n" |  | ||||||
|                  "    jnz 0\n" |  | ||||||
|                  "    mov %%3, [%%1 + %%2]\n", |  | ||||||
|       {sp_reg, to_string(-f->getStackFrameSize() - 120), scratch_reg, |  | ||||||
|        to_string(num_locs), to_string(m_init_value)}); |  | ||||||
| 
 |  | ||||||
|   newInsns[4]->setTarget(newInsns[2]); // Link jnz to L1.
 |  | ||||||
| 
 |  | ||||||
|   // bump stats
 |  | ||||||
|   m_num_transformed++; |  | ||||||
| } |  | ||||||
| @ -1,61 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| 
 |  | ||||||
| #include <irdb-core> |  | ||||||
| #include <irdb-transform> |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // Put the transform in its own namespace
 |  | ||||||
| // just to keep the header files easy to read.
 |  | ||||||
| // This is not an IRDB transform requirement, just good coding practice.
 |  | ||||||
| //
 |  | ||||||
| namespace InitStack { |  | ||||||
| using namespace std; |  | ||||||
| using namespace IRDB_SDK; |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // This class handles initializing stack frames to a constant value
 |  | ||||||
| //
 |  | ||||||
| // Note:  Using private inheritence here for "principle of minimum access",
 |  | ||||||
| // but you can choose what's best for your needs.
 |  | ||||||
| //
 |  | ||||||
| class InitStack_t : private Transform_t { |  | ||||||
| public: |  | ||||||
|   // construct an object
 |  | ||||||
|   InitStack_t( |  | ||||||
|       FileIR_t *p_variantIR,             // the FileIR object to transform
 |  | ||||||
|       const string &p_function_filename, // the name of a file with functions to
 |  | ||||||
|                                          // transform. "" -> no file and
 |  | ||||||
|                                          // transform all functions
 |  | ||||||
|       int init_value = 0,    // the value to write when initializing the stack
 |  | ||||||
|       bool p_verbose = false // use verbose logging?
 |  | ||||||
|   ); |  | ||||||
| 
 |  | ||||||
|   // execute the transform
 |  | ||||||
|   // input: m_funcs_to_init the set of functions to transform, the fileIR to
 |  | ||||||
|   // transform output: the transformed fileIR, with extra instructions to init
 |  | ||||||
|   // stack frames return value: true -> success, false -> fail
 |  | ||||||
|   bool execute(); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|   // methods
 |  | ||||||
| 
 |  | ||||||
|   // read in the given file full of function names to transform (called from
 |  | ||||||
|   // constructor) input:   the filename and FileIR to transform output:
 |  | ||||||
|   // m_funcs_to_init with the functions listed in the file
 |  | ||||||
|   void readFunctionsFromFile(const string &p_filename); |  | ||||||
| 
 |  | ||||||
|   // initialize the stack for a given function
 |  | ||||||
|   // input:  the fileIR to transform
 |  | ||||||
|   // output: the transformed fileIR
 |  | ||||||
|   void initStack(Function_t *f); |  | ||||||
| 
 |  | ||||||
|   // data
 |  | ||||||
|   set<Function_t *> m_funcs_to_init; // the functions whose stacks this object
 |  | ||||||
|                                      // should initialize
 |  | ||||||
|   int m_init_value;                  // the value with which to init the stack.
 |  | ||||||
|   bool m_verbose;                    // do verbose logging
 |  | ||||||
|   int m_num_transformed; // stats about how many functions that this object has
 |  | ||||||
|                          // transformed
 |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| } // namespace InitStack
 |  | ||||||
| @ -1,149 +0,0 @@ | |||||||
| #include "initialize_stack.hpp" |  | ||||||
| #include <getopt.h> |  | ||||||
| 
 |  | ||||||
| using namespace std; |  | ||||||
| using namespace IRDB_SDK; |  | ||||||
| using namespace InitStack; |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // Print usage info
 |  | ||||||
| //
 |  | ||||||
| void usage(char *p_name) { |  | ||||||
|   cerr << "Usage: " << p_name << " <variant_id>\n"; |  | ||||||
|   cerr << "\t[--functions <file> | -f <file>]       Read in the functions to " |  | ||||||
|           "auto-initialize      " |  | ||||||
|        << endl; |  | ||||||
|   cerr << "\t[--initvalue <value> | -i <value>]     Specify stack " |  | ||||||
|           "initialization value (default=0)" |  | ||||||
|        << endl; |  | ||||||
|   cerr << "\t[--verbose | -v]                       Verbose mode               " |  | ||||||
|           "                   " |  | ||||||
|        << endl; |  | ||||||
|   cerr << "\t[--help,--usage,-?,-h]                 Display this message       " |  | ||||||
|           "                   " |  | ||||||
|        << endl; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // The entry point for a stand-alone executable transform.
 |  | ||||||
| // Note:  Thanos-enabled transforms are easier to write, faster to execute, and
 |  | ||||||
| // generally preferred. Stand-alone transforms may be useful if the transform
 |  | ||||||
| // has issues with memory leaks and/or memory errors. Memory issues in a stand
 |  | ||||||
| // alone transform cannot affect correctness of other transforms.
 |  | ||||||
| //
 |  | ||||||
| int main(int argc, char **argv) { |  | ||||||
|   //
 |  | ||||||
|   // Sanity check that the command line has at least a variant ID, otherwise we
 |  | ||||||
|   // won't know what variant to operate on.
 |  | ||||||
|   //
 |  | ||||||
|   if (argc < 2) { |  | ||||||
|     usage(argv[0]); |  | ||||||
|     exit(1); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // constant parameters read from argv
 |  | ||||||
|   const auto program_name = string(argv[0]); |  | ||||||
|   const auto variantID = atoi(argv[1]); |  | ||||||
| 
 |  | ||||||
|   // initial values of parameters to parse
 |  | ||||||
|   auto verbose = false; |  | ||||||
|   auto funcs_filename = string(); |  | ||||||
|   auto init_value = 0; |  | ||||||
| 
 |  | ||||||
|   // declare some options for the transform
 |  | ||||||
|   const char *short_opts = "f:i:v?h"; |  | ||||||
|   struct option long_options[] = {{"functions", required_argument, 0, 'f'}, |  | ||||||
|                                   {"initvalue", required_argument, 0, 'i'}, |  | ||||||
|                                   {"verbose", no_argument, 0, 'v'}, |  | ||||||
|                                   {"help", no_argument, 0, 'h'}, |  | ||||||
|                                   {"usage", no_argument, 0, '?'}, |  | ||||||
|                                   {0, 0, 0, 0}}; |  | ||||||
| 
 |  | ||||||
|   // parse the options in a standard getopts_long loop
 |  | ||||||
|   while (true) { |  | ||||||
|     int c = getopt_long(argc, argv, short_opts, long_options, nullptr); |  | ||||||
|     if (c == -1) |  | ||||||
|       break; |  | ||||||
|     switch (c) { |  | ||||||
|     case 'f': |  | ||||||
|       funcs_filename = optarg; |  | ||||||
|       cout << "Reading file with function specifiers: " << funcs_filename |  | ||||||
|            << endl; |  | ||||||
|       break; |  | ||||||
|     case 'i': |  | ||||||
|       init_value = strtoll(optarg, NULL, 0); |  | ||||||
|       cout << "     Stack initialization value: " << hex << init_value << endl; |  | ||||||
|       break; |  | ||||||
|     case 'v': |  | ||||||
|       verbose = true; |  | ||||||
|       break; |  | ||||||
|     case '?': |  | ||||||
|     case 'h': |  | ||||||
|       usage(argv[0]); |  | ||||||
|       exit(1); |  | ||||||
|       break; |  | ||||||
|     default: |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // stand alone transforms must setup the interface to the sql server
 |  | ||||||
|   auto pqxx_interface = pqxxDB_t::factory(); |  | ||||||
|   BaseObj_t::setInterface(pqxx_interface.get()); |  | ||||||
| 
 |  | ||||||
|   // stand alone transforms must create and read a variant ID from the database
 |  | ||||||
|   auto pidp = VariantID_t::factory(variantID); |  | ||||||
|   assert(pidp->isRegistered() == true); |  | ||||||
| 
 |  | ||||||
|   // stand alone transforms must create and read the main file's IR from the
 |  | ||||||
|   // datatbase
 |  | ||||||
|   auto this_file = pidp->getMainFile(); |  | ||||||
|   auto url = this_file->getURL(); |  | ||||||
| 
 |  | ||||||
|   // declare for later so we can return the right value
 |  | ||||||
|   auto success = false; |  | ||||||
| 
 |  | ||||||
|   // now try to load the IR and execute a transform
 |  | ||||||
|   try { |  | ||||||
|     // Create and download the file's IR.
 |  | ||||||
|     // Note:  this is achieved differently  with thanos-enabled plugins
 |  | ||||||
|     auto firp = FileIR_t::factory(pidp.get(), this_file); |  | ||||||
| 
 |  | ||||||
|     // sanity
 |  | ||||||
|     assert(firp && pidp); |  | ||||||
| 
 |  | ||||||
|     // log
 |  | ||||||
|     cout << "Transforming " << this_file->getURL() << endl; |  | ||||||
| 
 |  | ||||||
|     // create and invoke the transform
 |  | ||||||
|     InitStack_t is(firp.get(), funcs_filename, init_value, verbose); |  | ||||||
|     success = is.execute(); |  | ||||||
| 
 |  | ||||||
|     // conditionally write the IR back to the database on success
 |  | ||||||
|     if (success) { |  | ||||||
|       cout << "Writing changes for " << url << endl; |  | ||||||
| 
 |  | ||||||
|       // Stand alone trnasforms must manually write the IR back to the IRDB and
 |  | ||||||
|       // commit the transactions
 |  | ||||||
|       firp->writeToDB(); |  | ||||||
| 
 |  | ||||||
|       // and commit the the transaction to postgres
 |  | ||||||
|       pqxx_interface->commit(); |  | ||||||
|     } else { |  | ||||||
|       cout << "Skipping write back on failure. " << url << endl; |  | ||||||
|     } |  | ||||||
|   } catch (const DatabaseError_t &db_error) { |  | ||||||
|     // log any databse errors that might come up in the transform process
 |  | ||||||
|     cerr << program_name << ": Unexpected database error: " << db_error |  | ||||||
|          << "file url: " << url << endl; |  | ||||||
|   } catch (...) { |  | ||||||
|     // log any other errors
 |  | ||||||
|     cerr << program_name << ": Unexpected error file url: " << url << endl; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   //
 |  | ||||||
|   // return success code to driver (as a shell-style return value).  0=success,
 |  | ||||||
|   // 1=warnings, 2=errors
 |  | ||||||
|   //
 |  | ||||||
|   return success ? 0 : 2; |  | ||||||
| } |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ludwig Lehnert
						Ludwig Lehnert