Skip to content
Snippets Groups Projects
Commit 67c6b8ba authored by Matthew McGill's avatar Matthew McGill
Browse files

Interface changes

Former-commit-id: d11ee2a0bc2d48d2305abfe9522540efd79a930b
parent f5f41e77
No related branches found
No related tags found
No related merge requests found
...@@ -36,7 +36,7 @@ namespace libIRDB ...@@ -36,7 +36,7 @@ namespace libIRDB
#include <util/insn_preds.hpp> #include <util/insn_preds.hpp>
#include <util/IBT_Provenance.hpp> #include <util/IBT_Provenance.hpp>
#include <util/params.hpp> #include <util/params.hpp>
#include <util/IR_Files.hpp> #include <util/IRDB_Objects.hpp>
}; };
......
#ifndef IRDB_Objects_h
#define IRDB_Objects_h
#include <map>
#include <utility>
#include <memory>
// TODO: Should really use unordered maps but was getting build errors
// *** A toolchain step should NOT delete pointers to any variant, file IR, or file object stored
// in a IRFiles_t object. I have made pointers shared where possible to communicate this. ***
class IRDBObjects_t
{
public:
IRDBObjects_t()
{
// set up interface to the sql server
BaseObj_t::SetInterface(&pqxx_interface);
};
~IRDBObjects_t();
// Add/delete file IRs for a variant. Takes in the base ID of the
// file (File_t) that the FileIR_t is paired with.
// Cannot delete a file IR if it is also owned outside this object.
// When deleting file IRs, have the option to write back to the DB.
// If the write fails, the IR is still deleted.
int AddFileIR(db_id_t variant_id, db_id_t file_id);
int DeleteFileIR(db_id_t file_id, bool write_to_DB);
// Add or delete a variant
// When deleting a variant, have the option to write back to the DB.
// Cannot delete a variant if it or its files are also owned outside this object.
// If the write fails, the variant is still deleted.
// Writing a variant does NOT write its files' IRs, but DOES delete them!
int AddVariant(db_id_t variant_id);
int DeleteVariant(db_id_t variant_id, bool write_to_DB);
// get a variant
// returns shared_ptr(NULL) if no such variant
std::shared_ptr<VariantID_t> GetVariant(db_id_t variant_id);
// get a file IR
// returns shared_ptr(NULL) if no such file IR
std::shared_ptr<FileIR_t> GetFileIR(db_id_t file_id);
// get a file
// returns shared_ptr(NULL) if no such file
std::shared_ptr<File_t> GetFile(db_id_t file_id);
// Get DB interface
pqxxDB_t* GetDBInterface();
// Write back all variants and file IRs stored in this IRFiles_t object.
// Also removes all variants and file IRs even if some writes fail.
// Returns 1 if any writes fail.
// Does NOT commit changes.
bool WriteBackAll(void);
private:
pqxxDB_t pqxx_interface;
// maps for speed of finding needed files, file IRs and/or variants
// that have already been read from the DB
// maps variant id to variant
std::map<db_id_t, std::shared_ptr<VariantID_t>> variant_map;
// maps file id to (file, file ir)
std::map<db_id_t, std::pair<std::shared_ptr<File_t>, std::shared_ptr<FileIR_t>>> file_IR_map;
};
#endif
#ifndef IR_Files_h
#define IR_Files_h
// TODO: This should really use unordered maps and sets,
// but I was having trouble building with those.
#include <map>
#include <utility>
#include <memory>
#include <set>
// If our toolchain use paradigm changes, this class can be extended
// to support adding, removing, writing back, and getting individual file IRs
// in a variant (may require adding more maps).
// *** A toolchain step should NOT delete pointers to any variant, file IR, or file object stored
// in a IRFiles_t object. I have made pointers shared where possible to communicate this. ***
class IRFiles_t
{
public:
IRFiles_t() {};
~IRFiles_t();
// Add/remove file IRs.
// Adding file IRs also adds the variant the files belong to.
// Removing file IRs also removes the variant the files belong to.
// When removing file IRs, have the option to write back to the DB.
int AddFileIRs(db_id_t variant_id);
int RemoveFileIRs(db_id_t variant_id, bool write_to_DB);
// get a variant
std::shared_ptr<VariantID_t> GetVariant(db_id_t variant_id);
// get file IRs (returns a shared ptr to a set of shared ptrs to file IRs)
std::shared_ptr<std::set<std::shared_ptr<FileIR_t>>> GetFileIRs(db_id_t variant_id);
// Write back all variants and file IRs stored in this IRFiles_t object.
int WriteBackAll(void);
private:
// maps for speed of finding needed file IRs and/or variants
// that have already been read from the DB
std::map<db_id_t, std::shared_ptr<VariantID_t>> variant_map;
std::map<db_id_t, std::shared_ptr<std::set<std::shared_ptr<FileIR_t>>>> file_IRs_map;
};
#endif
#include <map>
#include <libIRDB-core.hpp>
#include <libIRDB-util.hpp>
#include <utils.hpp>
#include <utility>
#include <memory>
#include <assert.h>
using namespace libIRDB;
using namespace std;
IRDBObjects_t::~IRDBObjects_t()
{
// All dynamically allocated members (DB objects)
// are held as shared pointers and don't need to be
// explicitly deleted.
}
int IRDBObjects_t::AddFileIR(db_id_t variant_id, db_id_t file_id)
{
map<db_id_t, pair<shared_ptr<File_t>, shared_ptr<FileIR_t>>>::iterator
it = file_IR_map.find(file_id);
if(it == file_IR_map.end())
{
return 1;
}
else
{
if(it->second.second == NULL)
{
File_t* the_file = (it->second.first).get();
assert(the_file != NULL);
assert(variant_map.find(variant_id) != variant_map.end());
VariantID_t& the_variant = *(variant_map.at(variant_id).get());
it->second.second = make_shared<FileIR_t>(the_variant, the_file);
assert(it->second.second != NULL);
}
return 0;
}
}
int IRDBObjects_t::DeleteFileIR(db_id_t file_id, bool write_to_DB)
{
int ret_status = 0;
map<db_id_t, pair<shared_ptr<File_t>, shared_ptr<FileIR_t>>>::iterator
it = file_IR_map.find(file_id);
if(it == file_IR_map.end())
{
ret_status = 1;
}
else
{
if(it->second.second != NULL)
{
assert(it->second.second.unique());
if(write_to_DB)
{
shared_ptr<File_t> the_file = it->second.first;
assert(the_file != NULL);
try
{
cout<<"Writing changes for "<<the_file->GetURL()<<endl;
(it->second.second)->WriteToDB();
}
catch (DatabaseError_t pnide)
{
cerr << "Unexpected database error: " << pnide << "file url: " << the_file->GetURL() << endl;
ret_status = 2;
}
catch (...)
{
cerr << "Unexpected error file url: " << the_file->GetURL() << endl;
ret_status = 2;
}
}
(it->second.second).reset();
}
}
return ret_status;
}
int IRDBObjects_t::AddVariant(db_id_t variant_id)
{
shared_ptr<VariantID_t> the_variant = make_shared<VariantID_t>(variant_id);
assert(the_variant->IsRegistered()==true);
pair<db_id_t, shared_ptr<VariantID_t>> var_pair = make_pair(variant_id, the_variant);
variant_map.insert(var_pair);
// add files
for(set<File_t*>::iterator it=the_variant->GetFiles().begin();
it!=the_variant->GetFiles().end();
++it
)
{
shared_ptr<File_t> curr_file(*it);
shared_ptr<FileIR_t> curr_file_IR;
pair<shared_ptr<File_t>, shared_ptr<FileIR_t>> file_IR_pair = make_pair(curr_file, curr_file_IR);
pair<db_id_t, pair<shared_ptr<File_t>, shared_ptr<FileIR_t>>> file_map_pair = make_pair((*it)->GetBaseID(), file_IR_pair);
file_IR_map.insert(file_map_pair);
}
return 0;
}
int IRDBObjects_t::DeleteVariant(db_id_t variant_id, bool write_to_DB)
{
int ret_status = 0;
map<db_id_t, shared_ptr<VariantID_t>>::iterator var_it = variant_map.find(variant_id);
if(var_it == variant_map.end())
{
ret_status = 1;
}
else
{
bool files_being_shared = false;
for(set<File_t*>::iterator file_it=var_it->second->GetFiles().begin();
file_it!=var_it->second->GetFiles().end();
++file_it
)
{
assert(file_IR_map.find((*file_it)->GetBaseID()) != file_IR_map.end());
pair<shared_ptr<File_t>, shared_ptr<FileIR_t>> file_IR_pair = file_IR_map.at((*file_it)->GetBaseID());
if(!file_IR_pair.first.unique() || !file_IR_pair.second.unique())
{
files_being_shared = true;
}
}
assert(!files_being_shared);
assert(var_it->second.unique());
if(write_to_DB)
{
try
{
cout<<"Writing changes for variant "<<variant_id<<endl;
var_it->second->WriteToDB();
}
catch (DatabaseError_t pnide)
{
cerr << "Unexpected database error: " << pnide << "variant ID: " << variant_id << endl;
ret_status = 2;
}
catch (...)
{
cerr << "Unexpected error variant ID: " << variant_id << endl;
ret_status = 2;
}
}
// remove files and file IRs
for(set<File_t*>::iterator file_it2=var_it->second->GetFiles().begin();
file_it2!=var_it->second->GetFiles().end();
++file_it2
)
{
file_IR_map.erase((*file_it2)->GetBaseID());
}
// remove variant
variant_map.erase(variant_id);
}
return ret_status;
}
bool IRDBObjects_t::WriteBackAll(void)
{
bool all_successes = true;
// Write back FileIRs
for(map<db_id_t, pair<shared_ptr<File_t>, shared_ptr<FileIR_t>>>::iterator
it = file_IR_map.begin();
it != file_IR_map.end();
++it
)
{
int result = IRDBObjects_t::DeleteFileIR((it->second.first)->GetBaseID(), true);
if(result != 0)
{
all_successes = false;
}
}
// Write back Variants
for(map<db_id_t, shared_ptr<VariantID_t>>::iterator
it2 = variant_map.begin();
it2 != variant_map.end();
++it2
)
{
int result = IRDBObjects_t::DeleteVariant((it2->second)->GetBaseID(), true);
if(result != 0)
{
all_successes = false;
}
}
return all_successes;
}
shared_ptr<VariantID_t> IRDBObjects_t::GetVariant(db_id_t variant_id)
{
map<db_id_t, shared_ptr<VariantID_t>>::iterator it = variant_map.find(variant_id);
if(it == variant_map.end())
{
shared_ptr<VariantID_t> null_var;
return null_var;
}
else
{
return it->second;
}
}
shared_ptr<FileIR_t> IRDBObjects_t::GetFileIR(db_id_t file_id)
{
map<db_id_t, pair<shared_ptr<File_t>, shared_ptr<FileIR_t>>>::iterator
it = file_IR_map.find(file_id);
if(it == file_IR_map.end())
{
shared_ptr<FileIR_t> null_fileIR;
return null_fileIR;
}
else
{
return it->second.second;
}
}
shared_ptr<File_t> IRDBObjects_t::GetFile(db_id_t file_id)
{
map<db_id_t, pair<shared_ptr<File_t>, shared_ptr<FileIR_t>>>::iterator
it = file_IR_map.find(file_id);
if(it == file_IR_map.end())
{
shared_ptr<File_t> null_file;
return null_file;
}
else
{
return it->second.first;
}
}
pqxxDB_t* IRDBObjects_t::GetDBInterface()
{
return &pqxx_interface;
}
#include <map>
#include <libIRDB-core.hpp>
#include <libIRDB-util.hpp>
#include <utils.hpp>
#include <utility>
#include <memory>
#include <iterator>
using namespace libIRDB;
using namespace std;
IRFiles_t::~IRFiles_t()
{
file_IR_map.clear(); // doesn't write back to DB
}
void IRFiles_t::AddFileIR(FileIR_t& IR_ref)
{
File_t* file_ptr = IR_ref.GetFile();
assert(file_ptr);
file_IR_map.insert(pair<File_t*, shared_ptr<FileIR_t>>(file_ptr, shared_ptr<FileIR_t>(&IR_ref)));
}
// may throw a database error exception if writing back to DB.
// If the write back fails, the FileIR will not be destroyed.
void IRFiles_t::RemoveFileIR(FileIR_t& IR_ref, bool write_to_DB)
{
if(!HasFileIR(IR_ref))
return;
if(write_to_DB)
IR_ref.WriteToDB();
File_t* file_ptr = IR_ref.GetFile();
assert(file_ptr);
file_IR_map.erase(file_ptr);
}
// may throw a database error exception if writing back to DB.
// If the write back fails, the FileIR will not be destroyed.
void IRFiles_t::RemoveFileIR(File_t& file_ref, bool write_to_DB)
{
if(!HasFileIR(file_ref))
return;
if(write_to_DB)
GetFileIR(file_ref)->WriteToDB();
file_IR_map.erase(&file_ref);
}
bool IRFiles_t::HasFileIR(File_t& file_ref)
{
map<File_t*, shared_ptr<FileIR_t>>::iterator got = file_IR_map.find(&file_ref);
if(got == file_IR_map.end())
return false;
else
return true;
}
bool IRFiles_t::HasFileIR(FileIR_t& IR_ref)
{
File_t* file_ptr = IR_ref.GetFile();
assert(file_ptr);
map<File_t*, shared_ptr<FileIR_t>>::iterator got = file_IR_map.find(file_ptr);
if(got == file_IR_map.end())
return false;
else
return true;
}
FileIR_t* IRFiles_t::GetFileIR(File_t& file_ref)
{
map<File_t*, shared_ptr<FileIR_t>>::iterator got = file_IR_map.find(&file_ref);
if(got == file_IR_map.end())
return NULL;
else
return (got->second).get();
}
...@@ -10,7 +10,7 @@ files= ''' ...@@ -10,7 +10,7 @@ files= '''
insn_preds.cpp insn_preds.cpp
IBT_Provenance.cpp IBT_Provenance.cpp
params.cpp params.cpp
IR_Files.cpp IRDB_Objects.cpp
''' '''
cpppath=''' cpppath='''
$SECURITY_TRANSFORMS_HOME/include/ $SECURITY_TRANSFORMS_HOME/include/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment