Commit 96f34d5e authored by Jason Hiser's avatar Jason Hiser 🚜

code cleanup during code review

parent c00d2b0d
Pipeline #2553 failed with stages
in 27 seconds
import os
#
# import the environment and clone it so we can make changes.
#
Import('env')
irdb_env=env.Clone()
irdb_env.Append(CXXFLAGS=" -std=c++11 -Wall -Werror -fmax-errors=2 " )
irdb_env.Append(LIBS= Split("irdb-core irdb-transform" ))
irdb_env.Append(CPPPATH= " $IRDB_SDK/include " )
irdb_env.Append(LIBPATH= Split(" "+os.environ['PEASOUP_HOME']+"/irdb-libs/lib "))
irdb_env.Replace(INSTALL_PATH=os.environ['PWD']+"/plugins_install" )
#
# These settings are recommended, but you can choose what you like
#
irdb_env.Append(CXXFLAGS=" -Wall -Werror -fmax-errors=2 " ) # be strict about syntax/warnings
irdb_env.Append(LIBS= Split("irdb-core irdb-transform" )) # link against core and transform libraries
irdb_env.Append(CPPPATH= " $IRDB_SDK/include " ) # be able to include the SDK files
irdb_env.Append(LIBPATH= Split(" $IRDB_LIBS " )) # this is where the libraries are.
irdb_env.Replace(INSTALL_PATH=os.environ['PWD']+"/plugins_install" ) # this is where to place plugins.
#
# export the new environment for children subconstructs
#
Export('irdb_env')
#
# include the child sconscript files.
#
dirs=Split("initialize_stack kill_deads stack_stamp")
libs = list()
for dir in dirs:
lib=irdb_env.SConscript(dir+"/SConscript", variant_dir='scons_build/'+dir)
libs = libs + lib
libs = libs + irdb_env.SConscript(dir+"/SConscript")
#
# And we are done
#
Return('libs')
import os
#
# create a basic scons environment
#
env=Environment()
#
# Include environment variables. These lines throw semi-readable errors if environment is not defined properly.
#
env.Replace(COOKBOOK_HOME=os.environ['COOKBOOK_HOME']) # add cookbook home var to env. for other scons files
env.Replace(IRDB_SDK=os.environ['IRDB_SDK']) # IRDB_SDK and IRDB_LIB by convention to find headers and libraries.
env.Replace(IRDB_LIBS=os.environ['IRDB_LIBS'])
# default build options
env.Replace(CFLAGS="-fPIC -Wall ")
env.Replace(CXXFLAGS="-fPIC -Wall ")
env.Replace(LINKFLAGS="-fPIC -Wall ")
# parse arguments
env.Replace(COOKBOOK_HOME=os.environ['COOKBOOK_HOME'])
env.Replace(IRDB_SDK=os.environ['IRDB_SDK'])
env.Replace(debug=ARGUMENTS.get("debug",0))
#
# Check for "debug=1" on the scons command line
#
env.Replace(debug=ARGUMENTS.get("debug",0)) # build in debug mode?
#
# Required: need these flag to appropriately include/link IRDB files.
#
env.Append(CXXFLAGS=" -std=c++11 ") # enable c++11
env.Append(LINKFLAGS=" -Wl,-unresolved-symbols=ignore-in-shared-libs ") # irdb libs may have symbols that resolve OK at runtime, but not linktime.
env.Append(LINKFLAGS=" -Wl,-unresolved-symbols=ignore-in-shared-libs ")
# if we are building in debug mode, use -g, else use -O
if int(env['debug']) == 1:
print "Setting debug mode"
env.Append(CFLAGS=" -g ")
......@@ -26,10 +35,10 @@ if int(env['debug']) == 1:
env.Append(SHLINKFLAGS=" -g ")
else:
print "Setting release mode"
env.Append(CFLAGS=" -O3 ")
env.Append(CXXFLAGS=" -O3 ")
env.Append(LINKFLAGS=" -O3 ")
env.Append(SHLINKFLAGS=" -O3 ")
env.Append(CFLAGS=" -O ")
env.Append(CXXFLAGS=" -O ")
env.Append(LINKFLAGS=" -O ")
env.Append(SHLINKFLAGS=" -O ")
Export('env')
......
import os
# import and create a copy of the environment so we don't screw up anyone elses env.
# import and create a copy of the environment so we don't mess
# up anyone else's env.
Import('irdb_env')
myenv=irdb_env.Clone()
# set input files and output program name
files=Glob( Dir('.').srcnode().abspath+"/*.cpp")
files=Glob( Dir('.').srcnode().abspath+"/*.cpp" )
pgm_name="initialize_stack.exe"
# build, install and return the program.
# 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')
env=Environment()
Export('env')
lib=SConscript("SConscript")
......@@ -24,29 +24,35 @@
#include <algorithm>
#include <math.h>
// todo: remove these lines
#define MIN_STACK_FRAME_SIZE 0
#define MAX_STACK_FRAME_SIZE 8000000
#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_functionsFilename, int p_initValue, bool p_verbose)
:
Transform(p_variantIR),
m_initValue(p_initValue),
Transform(p_variantIR), // initialize the Transform class so things like insertAssembly and getFileIR() can be used
m_initValue(p_initValue), // member variable inits
m_verbose(p_verbose),
m_numTransformed(0)
{
if (p_functionsFilename=="")
{
cout << "Auto-initialize all functions" << endl;
m_funcsToInit = getFileIR()->getFunctions();
m_funcsToInit = getFileIR()->getFunctions(); // use all functions from the IR
}
else
{
cout << "Auto-initialize functions specified in: " << p_functionsFilename << endl;
readFunctionsFromFile(p_functionsFilename);
readFunctionsFromFile(p_functionsFilename); // read functions from file
}
}
......@@ -57,40 +63,45 @@ InitStack_t::InitStack_t(FileIR_t *p_variantIR, const string& p_functionsFilenam
*/
void InitStack_t::readFunctionsFromFile(const string &p_filename)
{
ifstream functionsFile(p_filename);
const auto &all_funcs=getFileIR()->getFunctions();
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);
auto line = string();
while(functionsFile >> line)
{
for(auto f : getFileIR()->getFunctions())
const auto func_it=find_if(ALLOF(all_funcs), [&](const Function_t* f)
{
return f->getName() == line;
});
if(func_it!=end(all_funcs))
{
if (f && f->getName() == line)
{
m_funcsToInit.insert(f);
cout <<"Adding " << line << " to function list" << endl;
}
};
auto f=*func_it;
cout <<"Adding " << f->getName() << " to function list" << endl;
m_funcsToInit.insert(f);
}
}
}
/*
* Execute the transform.
* 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
*
*/
int InitStack_t::execute()
bool InitStack_t::execute()
{
// transform all functions
for(auto f : m_funcsToInit)
{
if (f == nullptr ) continue;
// todo: remove this
if (f->getName().substr(0, 1) == ".") continue; /* anh: ??? */
initStack(f);
};
}
// #ATTRIBUTE is a convention used to help find useful information in log files
cout << "#ATTRIBUTE InitStack::numTransformed=" << m_numTransformed << endl;
return m_numTransformed>0; // true means success
......@@ -109,6 +120,7 @@ void InitStack_t::initStack(Function_t* f)
const auto frame_size = f->getStackFrameSize();
const auto num_locs = static_cast<uint64_t> (ceil(frame_size / 4.0));
// todo: remove this line
if (frame_size <= MIN_STACK_FRAME_SIZE || frame_size >= MAX_STACK_FRAME_SIZE) return;
/* debug output */
......@@ -118,21 +130,24 @@ void InitStack_t::initStack(Function_t* f)
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_initValue << 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";
// assume: flags dead at function entry.
// and insert these instructions at the start of the function
auto i=entry;
insertAssemblyBefore (i, string()+"mov ["+sp_reg+"+"+to_string(-f->getStackFrameSize()-100)+"], "+scratch_reg);
i = insertAssemblyAfter (i, string()+"mov "+scratch_reg+", -" + to_string(num_locs));
const auto L1 = i = insertAssemblyAfter (i, string()+"mov dword ["+sp_reg+"+"+scratch_reg+"*4-4], " + to_string(m_initValue));
i = insertAssemblyAfter (i, string()+"inc "+scratch_reg);
i = insertAssemblyAfter (i, string()+"jnz 0", L1);
i = insertAssemblyAfter (i, string()+"mov "+scratch_reg+", ["+sp_reg+"+"+to_string(-f->getStackFrameSize()-100)+"] ");
// assume: flags and scratch_reg are dead at function entry.
// insert these instructions at the start of the function (to initialize the stack frame before the function runs)
auto tmp=entry;
//todo: anh to comment assembly and explain -100 constant.
insertAssemblyBefore (tmp, string()+"mov ["+sp_reg+"+"+to_string(-f->getStackFrameSize()-100)+"], "+scratch_reg);
tmp = insertAssemblyAfter (tmp, string()+"mov "+scratch_reg+", -" + to_string(num_locs));
const auto L1 = tmp = insertAssemblyAfter (tmp, string()+"mov dword ["+sp_reg+"+"+scratch_reg+"*4-4], " + to_string(m_initValue));
tmp = insertAssemblyAfter (tmp, string()+"inc "+scratch_reg);
tmp = insertAssemblyAfter (tmp, string()+"jnz 0", L1); // jnz to L1
tmp = insertAssemblyAfter (tmp, string()+"mov "+scratch_reg+", ["+sp_reg+"+"+to_string(-f->getStackFrameSize()-100)+"] ");
m_numTransformed++;
}
......@@ -24,34 +24,53 @@
#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.
//
namespace InitStack
{
using namespace std;
using namespace IRDB_SDK;
// the actual transform.
//
// This class handles initializing stack frames to a constant value
//
class InitStack_t : public Transform
{
public:
// construct an object
InitStack_t(
FileIR_t *p_variantIR,
const string& p_functionFilename,
int initValue = 0,
bool p_verbose = false
FileIR_t *p_variantIR, // the FileIR object to transform
const string& p_functionFilename, // the name of a file with functions to transform. "" -> no file and transform all functions
int initValue = 0, // the value to write when initializing the stack
bool p_verbose = false // use verbose logging?
);
int execute();
private:
// execute the transform
// input: m_funcsToInit 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_funcsToInit with the functions listed in the file
void readFunctionsFromFile(const string &p_filename);
void initStack(Function_t* f);
private:
set<Function_t*> m_funcsToInit;
// initialize the stack for a given function
// input: the fileIR to transform
// output: the transformed fileIR
void initStack(Function_t* f);
int m_initValue;
bool m_verbose;
int m_numTransformed;
private: // data
set<Function_t*> m_funcsToInit; // the functions whose stacks this object should initialize
int m_initValue; // the value with which to init the stack.
bool m_verbose; // do verbose logging
int m_numTransformed; // stats about how many functions that this object has transformed
};
}
......
/* fix copyright headers in all files */
/* fix variable name schema (camelcase? underscores? p_'s m_'s */
/*
* Copyright (c) 2016, 2017 - University of Virginia
*
......@@ -26,13 +31,13 @@ using namespace std;
using namespace IRDB_SDK;
using namespace InitStack;
void usage(char* name)
void usage(char* p_name)
{
cerr<<"Usage: "<<name<<" <variant_id>\n";
cerr<<"\t[--functions <file> | -f <file>] Read in the functions to auto-initialize"<<endl;
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<<"[--help,--usage,-?,-h] Display this message "<<endl;
cerr<<"\t[--verbose | -v] Verbose mode "<<endl;
cerr<<"\t[--help,--usage,-?,-h] Display this message "<<endl;
}
......@@ -45,16 +50,16 @@ int main(int argc, char **argv)
}
// constant parameters read from argv
const auto programName = string(argv[0]);
const auto variantID = atoi(argv[1]);
const auto program_name = string(argv[0]);
const auto variantID = atoi(argv[1]);
// initial values of parameters to parse
auto verbose = false;
auto funcsFilename= string();
auto initValue = 0;
auto verbose = false;
auto funcs_filename = string();
auto init_value = 0;
// Parse some options for the transform
// parse 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'},
......@@ -64,7 +69,6 @@ int main(int argc, char **argv)
{0,0,0,0}
};
const char* short_opts="f:i:v?h";
while(true)
{
int index = 0;
......@@ -74,12 +78,12 @@ int main(int argc, char **argv)
switch(c)
{
case 'f':
funcsFilename=optarg;
cout<<"Reading file with function specifiers: "<<funcsFilename<<endl;
funcs_filename=optarg;
cout<<"Reading file with function specifiers: "<<funcs_filename<<endl;
break;
case 'i':
initValue=strtoll(optarg, NULL, 0);
cout<<" Stack initialization value: "<<hex<<initValue<<endl;
init_value=strtoll(optarg, NULL, 0);
cout<<" Stack initialization value: "<<hex<<init_value<<endl;
break;
case 'v':
verbose=true;
......@@ -94,56 +98,61 @@ int main(int argc, char **argv)
}
}
/* setup the interface to the sql server */
// setup the interface to the sql server
auto pqxx_interface=pqxxDB_t::factory();
BaseObj_t::setInterface(pqxx_interface.get());
// create and read a variant ID from the database
auto pidp=VariantID_t::factory(variantID);
assert(pidp->isRegistered()==true);
auto success = false;
// create and read the main file's IR from the datatbase
auto this_file = pidp->getMainFile();
auto firp = FileIR_t::factory(pidp.get(), this_file);
cout<<"Transforming "<<this_file->getURL()<<endl;
assert(firp && pidp);
// declare for later so we can return the right value
auto success=false;
// now try to load the IR and execute a transform
try
{
InitStack_t is(firp.get(), funcsFilename, initValue, verbose);
auto success=is.execute();
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 "<<this_file->getURL()<<endl;
firp->writeToDB();
success = true;
pqxx_interface->commit();
}
else
{
cout<<"Skipping (no changes) "<<this_file->getURL()<<endl;
cout<<"Skipping write back on failure. "<<this_file->getURL()<<endl;
}
}
catch (DatabaseError_t pnide)
catch (DatabaseError_t db_error)
{
cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->getURL() << endl;
// log any databse errors that might come up in the transform process
cerr << program_name << ": Unexpected database error: " << db_error << "file url: " << this_file->getURL() << endl;
}
catch (...)
{
cerr << programName << ": Unexpected error file url: " << this_file->getURL() << endl;
}
// if any transforms for any files succeeded, we commit
if (success)
{
cout<<"Commiting changes...\n";
pqxx_interface->commit();
// log any other errors
cerr << program_name << ": Unexpected error file url: " << this_file->getURL() << endl;
}
// Return success code to driver. 0=success, 1=warnings, 2=errors.
//
// return success code to driver (as a shell-style return value). 0=success, 1=warnings, 2=errors
//
return success ? 0 : 2;
}
......@@ -4,13 +4,25 @@ Import('irdb_env')
# import and create a copy of the environment so we don't screw up anyone elses env.
myenv=irdb_env.Clone()
#
# set the files to build and the output file name
#
files=Glob( Dir('.').srcnode().abspath+"/*.cpp")
pgm="kill_deads.exe"
pgm="libkill_deads.so"
#
# override the default libs as we need more libraries for this transform
#
libs=Split("irdb-core irdb-transform irdb-deep irdb-util ")
pgm=myenv.Program(pgm, files, LIBS=libs)
# build and install the transform, by default
pgm=myenv.SharedLibrary(pgm, files, LIBS=libs)
install=myenv.Install("$INSTALL_PATH/", pgm)
Default(install)
#
# and we're done
#
Return('install')
env=Environment()
Export('env')
lib=SConscript("SConscript")
import os
# import and create a copy of the environment so we don't screw up anyone elses env.
Import('irdb_env')
myenv=irdb_env.Clone()
# input fies and program name
files=Glob( Dir('.').srcnode().abspath+"/*.cpp")
pgm_name="libstack_stamp.so"
# add extra libraries needed for stck stamping
myenv.Append(LIBS= Split(" irdb-cfg irdb-util irdb-transform "))
# add extra libraries needed for stack stamping
myenv.Append(LIBS= Split(" irdb-cfg irdb-util "))
# build, install and return the program
# build, and install the program by default
pgm=myenv.SharedLibrary(pgm_name, files)
install=myenv.Install("$INSTALL_PATH/", pgm)
Default(install)
# and we're done
Return('install')
env=Environment()
Export('env')
lib=SConscript("SConscript")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment