diff --git a/libIRDB/include/core/IRDB_Objects.hpp b/libIRDB/include/core/IRDB_Objects.hpp index 41f59ecf4ec35ffa28361c65d44acd860fcffaff..8a301644dd2438600f41c40de0e3395e9c9e3642 100644 --- a/libIRDB/include/core/IRDB_Objects.hpp +++ b/libIRDB/include/core/IRDB_Objects.hpp @@ -41,9 +41,9 @@ class IRDBObjects_t pqxxDB_t* resetDBInterface(); // Write back variants and file IRs. Does NOT commit changes. - int writeBackFileIR(const db_id_t file_id); + int writeBackFileIR(const db_id_t file_id, std::ostream *verbose_logging=nullptr); int writeBackVariant(const db_id_t variant_id); // Does NOT write back its files' IRs - int writeBackAll(void); // Returns -1 if any writes fail. + int writeBackAll(std::ostream* verbose_logging=nullptr); // Returns -1 if any writes fail. void deleteAll(void); diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp index 7668dabaf3094753e0235894546627d1896356ea..d0b70244b35a70b1d3a796fb1ac889633840012b 100644 --- a/libIRDB/include/core/fileir.hpp +++ b/libIRDB/include/core/fileir.hpp @@ -37,7 +37,7 @@ class FileIR_t : public BaseObj_t virtual ~FileIR_t(); // DB operations - void WriteToDB(); + void WriteToDB(std::ostream *verbose_logging=&std::cerr); // accessors and mutators in one FunctionSet_t& GetFunctions() { return funcs; } @@ -169,9 +169,9 @@ class FileIR_t : public BaseObj_t void ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2insnMap, std::map<Instruction_t*, db_id_t> &unresolvedICFS); - void CleanupICFS(); - void GarbageCollectICFS(); - void DedupICFS(); + void CleanupICFS(std::ostream *verbose_logging=&std::cerr); + void GarbageCollectICFS(std::ostream *verbose_logging=&std::cerr); + void DedupICFS(std::ostream *verbose_logging=&std::cerr); std::clock_t ReadIRDB_start; diff --git a/libIRDB/src/core/IRDB_Objects.cpp b/libIRDB/src/core/IRDB_Objects.cpp index 17ea07d06eb9da606dd3038b6525043b5680ea49..894641d9a6cc8f768497fd2ea60fa0b7ebe5903f 100644 --- a/libIRDB/src/core/IRDB_Objects.cpp +++ b/libIRDB/src/core/IRDB_Objects.cpp @@ -49,7 +49,7 @@ FileIR_t* IRDBObjects_t::addFileIR(const db_id_t variant_id, const db_id_t file_ } } -int IRDBObjects_t::writeBackFileIR(const db_id_t file_id) +int IRDBObjects_t::writeBackFileIR(const db_id_t file_id, ostream *verbose_logging) { const auto it = file_IR_map.find(file_id); @@ -65,7 +65,7 @@ int IRDBObjects_t::writeBackFileIR(const db_id_t file_id) // make sure static variable is set in the calling module -- IMPORTANT const auto & the_fileIR = (it->second).fileIR; the_fileIR->SetArchitecture(); - the_fileIR->WriteToDB(); + the_fileIR->WriteToDB(verbose_logging); return 0; } catch (DatabaseError_t pnide) @@ -180,14 +180,14 @@ void IRDBObjects_t::deleteVariant(const db_id_t variant_id) variant_map.erase(variant_id); } -int IRDBObjects_t::writeBackAll(void) +int IRDBObjects_t::writeBackAll(ostream *verbose_logging) { int ret_status = 0; // Write back FileIRs for(auto &file_pair : file_IR_map) { - const int result = IRDBObjects_t::writeBackFileIR((file_pair.second.file)->GetBaseID()); + const int result = IRDBObjects_t::writeBackFileIR((file_pair.second.file)->GetBaseID(), verbose_logging); if(result != 0) { ret_status = -1; diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index 7e93e6562928d909c63d44fe917b28702cf71997..1eef33f0b9288e351001fcd05f7e96ea15fef63f 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -37,6 +37,7 @@ using namespace std; #define SCOOP_CHUNK_SIZE (10*1024*1024) /* 10 mb */ +#define ALLOF(a) begin(a),end(a) #undef EIP @@ -281,7 +282,7 @@ void FileIR_t::AssembleRegistry() } instr->SetDataBits(rawBits); -// cerr << "doing instruction:" << ((Instruction_t*)instr)->getDisassembly() << " comment: " << ((Instruction_t*)instr)->GetComment() << endl; +// *verbose_logging << "doing instruction:" << ((Instruction_t*)instr)->getDisassembly() << " comment: " << ((Instruction_t*)instr)->GetComment() << endl; reg_val++; } @@ -709,7 +710,7 @@ void FileIR_t::ReadRelocsFromDB } -void FileIR_t::WriteToDB() +void FileIR_t::WriteToDB(ostream *verbose_logging) { // const auto WriteIRDB_start = clock(); @@ -722,7 +723,7 @@ void FileIR_t::WriteToDB() /* assign each item a unique ID */ SetBaseIDS(); - CleanupICFS(); + CleanupICFS(verbose_logging); db_id_t j=-1; @@ -797,7 +798,8 @@ void FileIR_t::WriteToDB() // in the IRDB, or have an associated "old" instruction. // without these bits of information, the new instruction can't possibly execute correctly. // and we won't have the information necessary to emit spri. - cerr << "NULL fallthrough: offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->GetComment() << endl; + + *verbose_logging << "NULL fallthrough: offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->GetComment() << endl; assert(0); abort(); } @@ -816,7 +818,7 @@ void FileIR_t::WriteToDB() // in the IRDB, or have an associated "old" instruction. // without these bits of information, the new instruction can't possibly execute correctly. // and we won't have the information necessary to emit spri. - cerr << "Call must have a target; offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->GetComment() << endl; + *verbose_logging << "Call must have a target; offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->GetComment() << endl; assert(0); abort(); } @@ -1313,53 +1315,21 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, } } -void FileIR_t::GarbageCollectICFS() +void FileIR_t::GarbageCollectICFS(ostream* verbose_logging) { - std::set<ICFS_t*> used_icfs; - - for(set<Instruction_t*>::const_iterator it=this->GetInstructions().begin(); - it!=this->GetInstructions().end(); - ++it) - { - Instruction_t* instr=*it; - if(instr && instr->GetIBTargets()) - { - used_icfs.insert(instr->GetIBTargets()); - } - } - -/* - int unused_icfs = this->GetAllICFS().size() - used_icfs.size(); - if (unused_icfs > 0) - { - cerr << "FileIR_t::GarbageCollectICFS(): WARNING: " << dec << unused_icfs << " unused ICFS found. "; - cerr << "Deleting before committing to IRDB" << endl; - } -*/ - - ICFSSet_t to_erase; - for(ICFSSet_t::const_iterator it=this->GetAllICFS().begin(); - it != this->GetAllICFS().end(); - ++it) - { - ICFS_t* icfs = *it; - if (used_icfs.count(icfs) == 0) - { - to_erase.insert(icfs); - } - } - - for(ICFSSet_t::const_iterator it=to_erase.begin(); - it != to_erase.end(); - ++it) - { - ICFS_t* icfs = *it; - this->GetAllICFS().erase(icfs); - } - + auto used_icfs= ICFSSet_t(); + // get the IBTarget of each instruction into used_icfs + transform( ALLOF(insns), inserter(used_icfs, begin(used_icfs)), + [](const Instruction_t* insn) -> ICFS_t* { return insn->GetIBTargets(); } + ); + // we likely inserted null into the set, which we just will remove as a special ase. + used_icfs.erase(nullptr); + + // update the list to include only the used ones. + icfs_set=used_icfs; } -void FileIR_t::DedupICFS() +void FileIR_t::DedupICFS(ostream *verbose_logging) { std::set<ICFS_t> unique_icfs; @@ -1380,8 +1350,8 @@ void FileIR_t::DedupICFS() if (duplicates.size() > 0) { - cerr << "FileIR_t::DedupICFS(): WARNING: " << dec << duplicates.size() << " duplicate ICFS out of " << all_icfs.size() << " total ICFS"; - cerr << ". De-duplicating before committing to IRDB" << endl; + *verbose_logging << "FileIR_t::DedupICFS(): WARNING: " << dec << duplicates.size() << " duplicate ICFS out of " << all_icfs.size() << " total ICFS"; + *verbose_logging << ". De-duplicating before committing to IRDB" << endl; } // remove duplicate icfs @@ -1404,7 +1374,7 @@ void FileIR_t::DedupICFS() if (*icfs == *t) { duplicate_map[icfs] = t; - cerr << "FileIR_t::DedupICFS(): remap: icfs id " << icfs->GetBaseID() << " --> icsf id " << t->GetBaseID() << endl; + *verbose_logging << "FileIR_t::DedupICFS(): remap: icfs id " << icfs->GetBaseID() << " --> icsf id " << t->GetBaseID() << endl; break; } } @@ -1423,10 +1393,10 @@ void FileIR_t::DedupICFS() } } -void FileIR_t::CleanupICFS() +void FileIR_t::CleanupICFS(ostream *verbose_logging) { - GarbageCollectICFS(); - DedupICFS(); + GarbageCollectICFS(verbose_logging); + DedupICFS(verbose_logging); } std::map<db_id_t,DataScoop_t*> FileIR_t::ReadScoopsFromDB diff --git a/tools/thanos/thanos.cpp b/tools/thanos/thanos.cpp index c48c0679aa41b4e3ad167d96c132ab316fb337dc..d80fcdafab62e618e4c400651c63c39747517c64 100644 --- a/tools/thanos/thanos.cpp +++ b/tools/thanos/thanos.cpp @@ -310,7 +310,7 @@ int ThanosPlugin_t::executeStep(TransformStep_t& the_step, const bool are_debugg pqxxDB_t* pqxx_interface = shared_objects->getDBInterface(); if(step_optional) { - const int error = shared_objects->writeBackAll(); + const int error = shared_objects->writeBackAll(&thanos_log); if(error) { return 1; // the failure must be from a critical step, abort @@ -350,7 +350,7 @@ int ThanosPlugin_t::executeStep(TransformStep_t& the_step, const bool are_debugg if(step_optional) { // write changes to DB to see if it succeeds - const int error = shared_objects->writeBackAll(); + const int error = shared_objects->writeBackAll(&thanos_log); if(error) { // abort changes by resetting DB interface @@ -366,7 +366,7 @@ int ThanosPlugin_t::executeStep(TransformStep_t& the_step, const bool are_debugg else if(are_debugging) { // write changes to DB in case next step fails - const int error = shared_objects->writeBackAll(); + const int error = shared_objects->writeBackAll(&thanos_log); if(error) { return 1; // critical step failed, abort @@ -386,7 +386,7 @@ int ThanosPlugin_t::executeStep(TransformStep_t& the_step, const bool are_debugg int ThanosPlugin_t::saveChanges() { pqxxDB_t* pqxx_interface = shared_objects->getDBInterface(); - const int error = shared_objects->writeBackAll(); + const int error = shared_objects->writeBackAll(&thanos_log); if(error) { return 1; // critical step failed, abort