From afefd319e0b67780109fc62e9a4dec3744f31fdb Mon Sep 17 00:00:00 2001 From: bdr7fv <bdr7fv@git.zephyr-software.com> Date: Sun, 23 Jun 2013 14:35:19 +0000 Subject: [PATCH] PN update. changed some logging data, changed how functions with low/no coveage are validated, add functionality to validate the entire program, including shared objects, at once. Former-commit-id: f3b7c9a6c2722f40ee997570bd9263682f7bbce9 --- tools/transforms/PNMain.cpp | 4 +- tools/transforms/PNTransformDriver.cpp | 200 ++++++++++++++----------- tools/transforms/PNTransformDriver.hpp | 4 +- 3 files changed, 114 insertions(+), 94 deletions(-) diff --git a/tools/transforms/PNMain.cpp b/tools/transforms/PNMain.cpp index f1252ad16..4578bdaa6 100644 --- a/tools/transforms/PNMain.cpp +++ b/tools/transforms/PNMain.cpp @@ -136,7 +136,7 @@ map<string, map<string,double> > getCoverageMap(char *filename,double cov_thresh if(func_name.length() > 0 && func_name[0] != '.') { - if(coverage >= cov_threshold) + if(coverage > cov_threshold) { if(func_name.length() > 0 && func_name[0] != '.') acceptable_cov++; @@ -149,7 +149,7 @@ map<string, map<string,double> > getCoverageMap(char *filename,double cov_thresh } cout<<"Summary:"<<endl; cout<<"\tTotal non-plt functions = "<<total_funcs<<endl; - cout<<"\tTotal non-plt functions exceeding or equal to "<<cov_threshold<<" threshold = "<<acceptable_cov<<" ("<<(double)acceptable_cov/total_funcs<<")"<<endl; + cout<<"\tTotal non-plt functions exceeding "<<cov_threshold<<" threshold = "<<acceptable_cov<<" ("<<(double)acceptable_cov/total_funcs<<")"<<endl; coverage_file.close(); } return coverage_map; diff --git a/tools/transforms/PNTransformDriver.cpp b/tools/transforms/PNTransformDriver.cpp index 3766901ed..86083ef1e 100644 --- a/tools/transforms/PNTransformDriver.cpp +++ b/tools/transforms/PNTransformDriver.cpp @@ -526,7 +526,7 @@ void PNTransformDriver::GenerateTransforms() { cout<<"PNTransformDriver: Shared Object Protection ON"<<endl; for(set<File_t*>::iterator it=pidp->GetFiles().begin(); - it!=pidp->GetFiles().end(); + it!=pidp->GetFiles().end()&&!timeExpired; ++it ) { @@ -843,31 +843,26 @@ void PNTransformDriver::GenerateTransformsHidden(map<string,double> &file_covera //the sorting approach I now do might sufficiently optimize that this //isn't necessary. Validate_Recursive(high_covered_funcs,0,high_covered_funcs.size()); - Validate_Recursive(low_covered_funcs,0,low_covered_funcs.size()); - - // //TODO: becaues I took out the register functionality to fix an apparent bug - // //I need to make sure P1 is transformed before registering. - // //If you bring back register finalized to actually transform, this shouldn't - // //cause an issue, but could be removed at that time. - // for(unsigned int i=0;i<not_covered_funcs.size();i++) - // { - // PNStackLayout* layout = not_covered_funcs[i].layouts[not_covered_funcs[i].layout_index]; - // Function_t *func = not_covered_funcs[i].func; - // Canary_Rewrite(layout,func); - // } - - // Register_Finalized(not_covered_funcs,0,not_covered_funcs.size()); //In theory, functions with no coverage will not have any benefit from validation //but coverage can sometimes be wrong. For example, if PIN failed, perhaps //the coverage reflects functions that were executed only if the test - //run fails. Go ahead ond attempt binary validation on non-covered functions. - Validate_Recursive(not_covered_funcs,0,not_covered_funcs.size()); + //run fails. Go ahead and attempt binary validation on non-covered functions. + //As an optimization I will validate non-covered funcs with functions with low coverage + //but in case a validation failure does occur, functions with no coverage + //are append to the low_covered_funcs vector. Appending to the end, as opposed to + //using one data structure for both should optimize binary search in the + //even of a validation failure, since all functions without coverage are clustered, + //and it is assumed functions with no coverage _SHOULD_ validate all the time. + low_covered_funcs.insert(low_covered_funcs.end(),not_covered_funcs.begin(),not_covered_funcs.end()); + Validate_Recursive(low_covered_funcs,0,low_covered_funcs.size()); - //TODO: do shuffle validation last. - cerr<<"Functions I will need to shuffle validate: "<<shuffle_validate_funcs.size()<<endl; - + //NOTE: if you decide to handle not_covered_funcs separately, + //make sure you either use Validate_Recursive, or rewrite + //the instructions yourself. + + cerr<<"Functions to shuffle validate: "<<shuffle_validate_funcs.size()<<endl; ShuffleValidation(shuffle_validate_funcs); high_coverage_count +=high_covered_funcs.size(); @@ -977,6 +972,7 @@ void PNTransformDriver::Register_Finalized(vector<validation_record> &vrs,unsign fr.layout = vrs[index].layouts[vrs[index].layout_index]; fr.func = vrs[index].func; fr.firp = orig_virp; + registered_firps.insert(orig_virp); finalization_registry.push_back(fr); //placing layout in the history here, although the information //could change when the modification is finalized. @@ -1120,89 +1116,89 @@ bool PNTransformDriver::Validate_Recursive(vector<validation_record> &vrs, unsig void PNTransformDriver::Finalize_Transformation() { cout<<"Finalizing Transformation: Committing all previously validated transformations ("<<finalization_registry.size()<<" functions)"<<endl; - set<FileIR_t*> firps; - - for(vector<finalize_record>::iterator it = finalization_registry.begin(); it != finalization_registry.end(); it++) - { - finalize_record fr = *it; - Function_t *func; - PNStackLayout *layout; - FileIR_t *firp; - - func = fr.func; - layout = fr.layout; - firp = fr.firp; - - assert(func != NULL && layout != NULL && firp != NULL); - firps.insert(firp); - -//DEBUG: This code needs to be put back, especially for removing canaries -//if do_canaries is false, but at the moment, accumulating modifications -//works for zsh, making it appear that delayed modification is broken. - - // orig_virp = firp; - - //Make sure any previous modificaitons are undone. - //undo(func); - - // //TODO: really there should be no need to retransform, but it - // //is much easier to retransform than to retain the modified - // //instructions previously made. - // if(do_canaries) - // Canary_Rewrite(layout,func); - // else - // Sans_Canary_Rewrite(layout,func); - } +// set<FileIR_t*> firps; + +// for(vector<finalize_record>::iterator it = finalization_registry.begin(); it != finalization_registry.end(); it++) +// { +// finalize_record fr = *it; +// Function_t *func; +// PNStackLayout *layout; +// FileIR_t *firp; + +// func = fr.func; +// layout = fr.layout; +// firp = fr.firp; + +// assert(func != NULL && layout != NULL && firp != NULL); +// firps.insert(firp); + +// //DEBUG: This code needs to be put back, especially for removing canaries +// //if do_canaries is false, but at the moment, accumulating modifications +// //works for zsh, making it appear that delayed modification is broken. + +// // orig_virp = firp; + +// //Make sure any previous modificaitons are undone. +// //undo(func); + +// // //TODO: really there should be no need to retransform, but it +// // //is much easier to retransform than to retain the modified +// // //instructions previously made. +// // if(do_canaries) +// // Canary_Rewrite(layout,func); +// // else +// // Sans_Canary_Rewrite(layout,func); +// } //TODO: one more validation? cerr<<"Sanity validation check....."<<endl; - string dirname = "p1.xform/validation_final"; - string cmd = "mkdir -p " + dirname; - system(cmd.c_str()); + // string dirname = "p1.xform/validation_final"; + // string cmd = "mkdir -p " + dirname; + // system(cmd.c_str()); - string aspri_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.aspri"; - string bspri_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.bspri"; + // string aspri_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.aspri"; + // string bspri_filename = string(get_current_dir_name()) + "/" + dirname + "/a.irdb.bspri"; - ofstream aspriFile; - aspriFile.open(aspri_filename.c_str(),ios_base::out); + // ofstream aspriFile; + // aspriFile.open(aspri_filename.c_str(),ios_base::out); - if(!aspriFile.is_open()) - { - assert(false); - } + // if(!aspriFile.is_open()) + // { + // assert(false); + // } - for(set<FileIR_t*>::iterator it=firps.begin(); - it!=firps.end(); - ++it - ) - { - FileIR_t *firp = *it; - firp->GenerateSPRI(aspriFile,false); - } + // for(set<FileIR_t*>::iterator it=firps.begin(); + // it!=firps.end(); + // ++it + // ) + // { + // FileIR_t *firp = *it; + // firp->GenerateSPRI(aspriFile,false); + // } - aspriFile.close(); + // aspriFile.close(); - char new_instr[1024]; - //This script generates the aspri and bspri files; it also runs BED - sprintf(new_instr, "%s %d %s %s", BED_script.c_str(), orig_progid, aspri_filename.c_str(), bspri_filename.c_str()); + // char new_instr[1024]; + // //This script generates the aspri and bspri files; it also runs BED + // sprintf(new_instr, "%s %d %s %s", BED_script.c_str(), orig_progid, aspri_filename.c_str(), bspri_filename.c_str()); - //If OK=BED(func), then commit - int rt=system(new_instr); - int actual_exit = -1, actual_signal = -1; - if (WIFEXITED(rt)) actual_exit = WEXITSTATUS(rt); - else actual_signal = WTERMSIG(rt); - int retval = actual_exit; - - if(retval != 0) - cerr<<"Sanity validation failed!! Continuing for now"<<endl; + // //If OK=BED(func), then commit + // int rt=system(new_instr); + // int actual_exit = -1, actual_signal = -1; + // if (WIFEXITED(rt)) actual_exit = WEXITSTATUS(rt); + // else actual_signal = WTERMSIG(rt); + // int retval = actual_exit; + + if( !Validate(NULL,"validation_final")) + cerr<<"Sanity validation failed!! Continuing for now."<<endl; else cerr<<"Sanity validation passed."<<endl; //Commit changes for each file. //TODO: is this necessary, can I do one write? - for(set<FileIR_t*>::iterator it=firps.begin(); - it!=firps.end(); + for(set<FileIR_t*>::iterator it=registered_firps.begin(); + it!=registered_firps.end(); ++it ) { @@ -1210,9 +1206,6 @@ void PNTransformDriver::Finalize_Transformation() cout<<"Writing to DB: "<<firp->GetFile()->GetURL()<<endl; firp->WriteToDB(); } - - - } void PNTransformDriver::Print_Report() @@ -1385,6 +1378,16 @@ bool PNTransformDriver::ShuffleValidation(int reps, PNStackLayout *layout,Functi return true; } +// Validate the modifications for the passed in FileIR_t*, creating +// a directory structure for the generated spri files in a directory +// reflecting the passed in string. +// +// If the FileIR_t* is null, Validate will generate spri +// for as FileIR_t* that have been registered in the FileIR_t* +// registry (entries in this structure are made whenever +// a function has been registered for finalization). +// Passing NULL essentially provides a mechanism of revalidating all +// previously modified and validated functions. bool PNTransformDriver::Validate(FileIR_t *virp, string name) { cerr<<"PNTransformDriver: Validate(): "<<name<<endl; @@ -1404,7 +1407,22 @@ bool PNTransformDriver::Validate(FileIR_t *virp, string name) } cerr<<"Pre genreate SPRI"<<endl; - virp->GenerateSPRI(aspriFile,false); // p1.xform/<function_name>/a.irdb.aspri + + if(virp == NULL) + { + //Generate spri for previous files + for(set<FileIR_t*>::iterator it=registered_firps.begin(); + it!=registered_firps.end(); + ++it + ) + { + FileIR_t *firp = *it; + firp->GenerateSPRI(aspriFile,false); + } + } + //generate spri for the current file + else + virp->GenerateSPRI(aspriFile,false); // p1.xform/<function_name>/a.irdb.aspri cerr<<"Post genreate SPRI"<<endl; aspriFile.close(); diff --git a/tools/transforms/PNTransformDriver.hpp b/tools/transforms/PNTransformDriver.hpp index 5bda4c3c2..ea0d55701 100644 --- a/tools/transforms/PNTransformDriver.hpp +++ b/tools/transforms/PNTransformDriver.hpp @@ -70,6 +70,7 @@ protected: std::vector<std::string> not_transformable; std::vector<libIRDB::Function_t*> failed; std::vector<finalize_record> finalization_registry; + std::set<FileIR_t*> registered_firps; int high_coverage_count, low_coverage_count, no_coverage_count, validation_count; // write stack objects to IRDB @@ -112,7 +113,8 @@ protected: virtual void Finalize_Transformation(); void Register_Finalized(std::vector<validation_record> &vrs,unsigned int start, int length); - bool Validate_Recursive(std::vector<validation_record> &vrs, unsigned int start, int length); + bool Validate_Recursive(std::vector<validation_record> &vrs, unsigned int start, int length);//,bool suspect=false); +// bool Validate_Linear(std::vector<validation_record> &vrs, unsigned int start, int length); public: static bool timeExpired; -- GitLab