diff --git a/PNMain.cpp b/PNMain.cpp index e00ff885080dc07407dcd03c810c2ac69f18c3c6..33d9c1e5f76581086c4c5768085051d8adefd71b 100644 --- a/PNMain.cpp +++ b/PNMain.cpp @@ -46,8 +46,12 @@ #include "globals.h" +// yaml includes +#include <yaml-cpp/yaml.h> + using namespace std; using namespace IRDB_SDK; +// using namespace YAML; // using namespace MEDS_Annotation; #define ALLOF(a) begin(a),end(a) @@ -248,6 +252,165 @@ std::string getStepName(void) const override return "p1transform"; } +// Read specified SLX transformation parameters, including per-function overrides, +// from specification file SLX.yaml and override the values that came from command-line +// args, which were obtained from parseArgs() below. +void parseYAML(void) +{ + bool FileExists = false; + if (FILE *YAMLFile = fopen("SLX.yaml", "r")) + { + FileExists = (0 == fclose(YAMLFile)); + } + + if (!FileExists) + { + cout << "File SLX.yaml does not exist." << endl; + return; + } + + YAML::Node basenode = YAML::LoadFile("SLX.yaml"); + if (basenode.IsNull()) + { + cout << "ERROR: Failure to load file SLX.yaml" << endl; + return; + } + + // Get the global defaults YAML node. + YAML::Node globalnode = basenode["global_policy"]; + if (globalnode.IsNull()) + { + cout << "WARNING: No global_policy YAML node found" << endl; + } + else + { + // Override parseArgs()-obtained values; log differences. + YAML::Node randomseednode = globalnode["random_seed"]; + if (!randomseednode.IsNull()) + { + string randomseedvalstr = randomseednode.as<std::string>(); + if (0 != randomseedvalstr.compare("<randomly selected value>")) + { + // A particular non-random value is specified so that runs + // can be duplicated. + int new_seed_value = stoi(randomseedvalstr, nullptr, 10); + int old_seed_value = pn_options->getRandomSeed(); + if (new_seed_value != old_seed_value) + { + cout << "YAML: Changing random seed from " << old_seed_value << " to " << new_seed_value << endl; + pn_options->setRandomSeed(new_seed_value); + } + } + } + + YAML::Node minstacknode = globalnode["min_stack_padding"]; + if (!minstacknode.IsNull()) + { + string minstackvalstr = minstacknode.as<std::string>(); + if (0 != minstackvalstr.compare("")) + { + // A particular minimum stack padding is specified. + int new_minpad_value = stoi(minstackvalstr, nullptr, 10); + int old_minpad_value = pn_options->getMinStackPadding(); + if (new_minpad_value != old_minpad_value) + { + cout << "YAML: Changing min stack padding from " << old_minpad_value << " to " << new_minpad_value << endl; + pn_options->setMinStackPadding(new_minpad_value); + } + } + } + + YAML::Node maxstacknode = globalnode["max_stack_padding"]; + if (!maxstacknode.IsNull()) + { + string maxstackvalstr = maxstacknode.as<std::string>(); + if (0 != maxstackvalstr.compare("")) + { + // A particular maximum stack padding is specified. + int new_maxpad_value = stoi(maxstackvalstr, nullptr, 10); + int old_maxpad_value = pn_options->getMaxStackPadding(); + if (new_maxpad_value != old_maxpad_value) + { + cout << "YAML: Changing max stack padding from " << old_maxpad_value << " to " << new_maxpad_value << endl; + pn_options->setMaxStackPadding(new_maxpad_value); + } + } + } + + YAML::Node recminstacknode = globalnode["recursive_min_stack_padding"]; + if (!recminstacknode.IsNull()) + { + string recminstackvalstr = recminstacknode.as<std::string>(); + if (0 != recminstackvalstr.compare("")) + { + // A particular minimum stack padding for recursive functions is specified. + int new_recminpad_value = stoi(recminstackvalstr, nullptr, 10); + int old_recminpad_value = pn_options->getRecursiveMinStackPadding(); + if (new_recminpad_value != old_recminpad_value) + { + cout << "YAML: Changing recursive min stack padding from " << old_recminpad_value << " to " << new_recminpad_value << endl; + pn_options->setRecursiveMinStackPadding(new_recminpad_value); + } + } + } + + YAML::Node recmaxstacknode = globalnode["recursive_max_stack_padding"]; + if (!recmaxstacknode.IsNull()) + { + string recmaxstackvalstr = recmaxstacknode.as<std::string>(); + if (0 != recmaxstackvalstr.compare("")) + { + // A particular maximum stack padding for recursive functions is specified. + int new_recmaxpad_value = stoi(recmaxstackvalstr, nullptr, 10); + int old_recmaxpad_value = pn_options->getRecursiveMaxStackPadding(); + if (new_recmaxpad_value != old_recmaxpad_value) + { + cout << "YAML: Changing recursive max stack padding from " << old_recmaxpad_value << " to " << new_recmaxpad_value << endl; + pn_options->setRecursiveMaxStackPadding(new_recmaxpad_value); + } + } + } + +#if 0 // auto_initialize is for the initialize_stack transform; never merged into p1transform. + YAML::Node autoinitnode = globalnode["auto_initialize"]; + if (!autoinitnode.IsNull()) + { + string autoinitvalstr = autoinitnode.as<std::string>(); + if (0 != autoinitvalstr.compare("")) + { + // A particular auto_initialize canary value is specified. + int new_autoinit_value = stoi(autoinitvalstr, nullptr, 10); + int old_autoinit_value = pn_options->getCanaryValue(); + if (new_autoinit_value != old_autoinit_value) + { + cout << "YAML: Changing auto_init canary value from " << old_autoinit_value << " to " << new_autoinit_value << endl; + pn_options->setCanaryValue(new_autoinit_value); + } + } + } +#endif + +#if 0 // canary types of float, top, and bottom do not seem to exist yet + YAML::Node canarytypenode = globalnode["canary_type"]; + if (!canarytypenode.IsNull()) + { + string canarytypevalstr = canarytypenode.as<std::string>(); + if (0 != canarytypevalstr.compare("")) + { + // A particular auto_initialize canary value is specified. + int new_autoinit_value = stoi(autoinitvalstr, nullptr, 10); + int old_autoinit_value = pn_options->getCanaryValue(); + if (new_autoinit_value != old_autoinit_value) + { + cout << "YAML: Changing auto_init canary value from " << old_autoinit_value << " to " << new_autoinit_value << endl; + pn_options->setCanaryValue(new_autoinit_value); + } + } + } +#endif + } + return; +} // end of parseYAML() int parseArgs(const vector<string> step_args) { @@ -491,6 +654,9 @@ int parseArgs(const vector<string> step_args) assert(pn_options->getMaxStackPadding() >= pn_options->getMinStackPadding()); assert(pn_options->getRecursiveMaxStackPadding() >= pn_options->getRecursiveMinStackPadding()); + // Override values using YAML specification file. + this->parseYAML(); + cout << "min_stack_padding: " << pn_options->getMinStackPadding() << endl; cout << "max_stack_padding: " << pn_options->getMaxStackPadding() << endl; cout << "recursive_min_stack_padding: " << pn_options->getRecursiveMinStackPadding() << endl; diff --git a/SConscript b/SConscript index 5038bcc9fe04e15a864a25317c003df403294016..5c70f53d18a611081523cbfb4124e25c0fc5c892 100644 --- a/SConscript +++ b/SConscript @@ -8,6 +8,7 @@ LIBS= " irdb-cfg irdb-transform irdb-core EXEIO " cpppath=''' $IRDB_SDK/include + $P1_HOME/third_party/yaml-cpp/include $PEASOUP_HOME/irdb-libs/libEXEIO/include ''' @@ -16,9 +17,22 @@ myenv.Append(LIBPATH=Split(libpath)) myenv.Append(CPPPATH=Split(cpppath)) +yamlcpp_files=Glob("third_party/yaml-cpp/src/*.cpp") +p1_files=Glob( Dir('.').srcnode().abspath+"/*.cpp" ) + +p2_files="P1_utility.cpp PNTransformDriver.cpp PNStackLayout.cpp \ +PNRange.cpp Range.cpp OffsetInference.cpp DirectOffsetInference.cpp \ +ScaledOffsetInference.cpp P1Inference.cpp PNRegularExpressions.cpp \ +PNMain.cpp StackLayout.cpp General_Utility.cpp \ +AnnotationBoundaryGenerator.cpp PrecedenceBoundaryInference.cpp \ +PNIrdbManager.cpp EhUpdater.cpp" + +all_files=p1_files+yamlcpp_files + +# Does not work; cannot concatenate a string and a Glob. +# all_files=p2_files+yamlcpp_files -all_files="P1_utility.cpp PNTransformDriver.cpp PNStackLayout.cpp PNRange.cpp Range.cpp OffsetInference.cpp DirectOffsetInference.cpp ScaledOffsetInference.cpp P1Inference.cpp PNRegularExpressions.cpp PNMain.cpp StackLayout.cpp General_Utility.cpp AnnotationBoundaryGenerator.cpp PrecedenceBoundaryInference.cpp PNIrdbManager.cpp EhUpdater.cpp" p1=myenv.SharedLibrary("p1transform.so", Split(all_files), LIBS=Split(LIBS)) install=myenv.Install("$P1_HOME/plugins_install/", p1) diff --git a/integertransformdriver.cpp b/integertransformdriver.cpp deleted file mode 100644 index e1cf735178a41d57f093db27779590f6cc456bb3..0000000000000000000000000000000000000000 --- a/integertransformdriver.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2013, 2014 - University of Virginia - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from the University - * of Virginia. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: University of Virginia - * e-mail: jwd@virginia.com - * URL : http://www.cs.virginia.edu/ - * - */ - -#include <stdlib.h> -#include <fstream> -#include <irdb-core> -#include <getopt.h> -#include <libgen.h> - -#include "MEDS_AnnotationParser.hpp" -#include "transformutils.h" -#include "integertransform.hpp" -#include "integertransform32.hpp" -#include "integertransform64.hpp" -#include "pointercheck64.hpp" - -// current convention -#define BINARY_NAME "a.ncexe" -#define ANNOTATION_SUFFIX ".infoannot" -#define SHARED_OBJECTS_DIR "shared_objects" - -using namespace std; -using namespace libTransform; - -bool saturating_arithmetic = false; -bool path_manip_detected = false; // deprecated -bool instrument_idioms = false; -bool warning_only = false; -bool check_pointers = false; - -void usage() -{ - cerr << "Usage: integertransformdriver.exe <variant_id> <filtered_functions> <integer.warning.addresses> [--saturate] [--instrument-idioms] [--check-pointers] [--warning]"<<endl; -} - -int parse_args(int p_argc, char* p_argv[]) -{ - int option = 0; - char options[] = "s:i:w:c"; - struct option long_options[] = { - {"saturate", no_argument, NULL, 's'}, - {"instrument-idioms", no_argument, NULL, 'i'}, - {"warning", no_argument, NULL, 'w'}, - {"check-pointers", no_argument, NULL, 'c'}, - {NULL, no_argument, NULL, '\0'}, // end-of-array marker - }; - - while ((option = getopt_long( - p_argc, - p_argv, - options, - long_options, - NULL)) != -1) - { - switch (option) - { - case 's': - { - saturating_arithmetic = true; - printf("saturating arithmetic enabled\n"); - break; - } - case 'i': - { - printf("instrument idioms enabled\n"); - instrument_idioms = true; - break; - } - case 'w': - { - printf("warning only mode\n"); - warning_only = true; - break; - } - case 'c': - { - printf("check pointers mode\n"); - check_pointers = true; - break; - } - default: - return 1; - } - } - return 0; -} - -std::set<VirtualOffset> getInstructionWarnings(char *warningFilePath) -{ - std::set<VirtualOffset> warnings; - ifstream warningsFile; - - warningsFile.open(warningFilePath); - - if (warningsFile.is_open()) - { - while (!warningsFile.eof()) - { - string address; - getline(warningsFile, address); - - if (!address.empty()) - { - VirtualOffset vo(address); - warnings.insert(vo); - - cerr << "Detected warning address at: 0x" << hex << vo.getOffset() << endl; - } - } - } - - warningsFile.close(); - - cerr << "Detected a total of " << warnings.size() << " benign addresses" << endl; - return warnings; -} - -int main(int argc, char **argv) -{ - if(argc < 4) - { - usage(); - exit(1); - } - - string programName(argv[0]); - int variantID = atoi(argv[1]); - set<string> filteredFunctions = getFunctionList(argv[2]); - char *integerWarnings = argv[3]; - - parse_args(argc, argv); - - VariantID_t *pidp=NULL; - - /* setup the interface to the sql server */ - pqxxDB_t pqxx_interface; - BaseObj_t::setInterface(&pqxx_interface); - - pidp=new VariantID_t(variantID); - assert(pidp->isRegistered()==true); - - bool one_success = false; - for(set<File_t*>::iterator it=pidp->getFiles().begin(); - it!=pidp->getFiles().end(); - ++it) - { - File_t* this_file = *it; - FileIR_t *firp = new FileIR_t(*pidp, this_file); - char *fileBasename = basename((char*)this_file->getURL().c_str()); - - assert(firp && pidp); - - try - { - string annotationFilename; - // need to map filename to integer annotation file produced by STARS - // this should be retrieved from the IRDB but for now, we use files to store annotations - // convention from within the peasoup subdirectory is: - // a.ncexe.infoannot - // shared_objects/<shared-lib-filename>.infoannot - if (strcmp(fileBasename, BINARY_NAME) == 0) - annotationFilename = string(BINARY_NAME) + string(ANNOTATION_SUFFIX); - else - annotationFilename = string(SHARED_OBJECTS_DIR) + "/" + fileBasename + ANNOTATION_SUFFIX; - - cerr << "annotation file: " << annotationFilename << endl; - - // parse MEDS integer annotations - ifstream annotationFile(annotationFilename.c_str(), ifstream::in); - if (!annotationFile.is_open()) - { - cerr << "annotation file not found: " << annotationFilename.c_str() << endl; - continue; - } - - MEDS_AnnotationParser annotationParser(annotationFile); - - // this is now wrong as we're instrumenting shared libraries - // we need to display file IDs along with the PC to distinguish between various libs - std::set<VirtualOffset> warnings = getInstructionWarnings(integerWarnings); // keep track of instructions that should be instrumented as warnings (upon detection, print diagnostic & continue) - - MEDS_Annotations_t annotations = annotationParser.getAnnotations(); - - cout << "integer transform driver: found " << annotations.size() << " annotations" << endl; - - // do the transformation - - libTransform::IntegerTransform *intxform = NULL; - if(firp->getArchitectureBitWidth()==64) - { - if (check_pointers) - { - intxform = new PointerCheck64(pidp, firp, &annotations, &filteredFunctions, &warnings); - intxform->setInstrumentIdioms(true); - } - else - intxform = new IntegerTransform64(pidp, firp, &annotations, &filteredFunctions, &warnings); - } - else - { - intxform = new IntegerTransform32(pidp, firp, &annotations, &filteredFunctions, &warnings); - } - - intxform->setSaturatingArithmetic(saturating_arithmetic); - intxform->setPathManipulationDetected(path_manip_detected); - intxform->setInstrumentIdioms(instrument_idioms); - intxform->setWarningsOnly(warning_only); - - int exitcode = intxform->execute(); - - if (exitcode == 0) - { - one_success = true; - firp->writeToDB(); - intxform->logStats(); - delete firp; - } - } - catch (DatabaseError_t pnide) - { - cerr << programName << ": Unexpected database error: " << pnide << "file url: " << this_file->getURL() << endl; - } - catch (...) - { - cerr << programName << ": Unexpected error file url: " << this_file->getURL() << endl; - } - } // end file iterator - - // if any integer transforms for any files succeeded, we commit - if (one_success) - pqxx_interface.Commit(); - - return 0; -} diff --git a/nulltransform.cpp b/nulltransform.cpp deleted file mode 100644 index b1951aecd6b3b5c4c69b4113edf28ff085962223..0000000000000000000000000000000000000000 --- a/nulltransform.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013, 2014 - University of Virginia - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from the University - * of Virginia. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: University of Virginia - * e-mail: jwd@virginia.com - * URL : http://www.cs.virginia.edu/ - * - */ - -#include <iostream> -#include "targ-config.h" - -#include "elfio/elfio.hpp" -#include "elfio/elfio_dump.hpp" - -#include "null_transform.h" - - -int main(int argc, char **argv) -{ - if (argc < 3) - { - std::cerr << "usage: " << argv[0] << " <elfFile> <annotationFile> [<spriFile>]" << std::endl; - return 1; - } - - std::cout << "Reading elf file:" << argv[1] << std::endl; - std::cout << "Reading MEDS annotation file:" << argv[2] << std::endl; - - NullTransform *nullTransform; - - if (argc == 3) - nullTransform = new NullTransform(argv[1], argv[2], (char*)"spri.out"); - else - nullTransform = new NullTransform(argv[1], argv[2], argv[3]); - - nullTransform->rewrite(); - - vector<wahoo::Function*> ncf = nullTransform->getNonCandidateFunctions(); - vector<wahoo::Function*> cf = nullTransform->getCandidateFunctions(); - vector<wahoo::Function*> af = nullTransform->getAllFunctions(); - - std::cout << "#functions: " << af.size() << std::endl; - std::cout << "#candidate functions: " << cf.size() << std::endl; - std::cout << "#non-candidate functions: " << ncf.size() << std::endl; -} diff --git a/transformutils.cpp b/transformutils.cpp deleted file mode 100644 index bfab574def792f06ceb16698ea8ba988f147ad0a..0000000000000000000000000000000000000000 --- a/transformutils.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013, 2014 - University of Virginia - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from the University - * of Virginia. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: University of Virginia - * e-mail: jwd@virginia.com - * URL : http://www.cs.virginia.edu/ - * - */ - -#include <iostream> -#include <fstream> -#include <string> - -#include "transformutils.h" - -using namespace std; - -set<string> getFunctionList(char *p_filename) -{ - set<string> functionList; - - ifstream candidateFile; - candidateFile.open(p_filename); - - if(candidateFile.is_open()) - { - while(!candidateFile.eof()) - { - string functionName; - getline(candidateFile, functionName); - - functionList.insert(functionName); - } - - candidateFile.close(); - } - - return functionList; -} -