From ae3d78faf54d566f27821ebf3360b5c5eec833c1 Mon Sep 17 00:00:00 2001 From: jdh8d <jdh8d@git.zephyr-software.com> Date: Fri, 13 Jul 2012 19:35:10 +0000 Subject: [PATCH] added missing file Former-commit-id: 703cbab221872c103c42694e2c22499824b7ee05 --- .gitattributes | 1 + libIRDB/src/core/fileir.cpp | 305 ++++++++++++++++++++++++++++++++++++ 2 files changed, 306 insertions(+) create mode 100644 libIRDB/src/core/fileir.cpp diff --git a/.gitattributes b/.gitattributes index 69bc14c8a..8ae740217 100644 --- a/.gitattributes +++ b/.gitattributes @@ -253,6 +253,7 @@ libIRDB/src/core/all.hpp -text libIRDB/src/core/baseobj.cpp -text libIRDB/src/core/dbinterface.cpp -text libIRDB/src/core/file.cpp -text +libIRDB/src/core/fileir.cpp -text libIRDB/src/core/function.cpp -text libIRDB/src/core/generate_spri.cpp -text libIRDB/src/core/instruction.cpp -text diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp new file mode 100644 index 000000000..20a71f040 --- /dev/null +++ b/libIRDB/src/core/fileir.cpp @@ -0,0 +1,305 @@ + +#include <all.hpp> +#include <utils.hpp> +#include <stdlib.h> +#include <map> +using namespace libIRDB; +using namespace std; + +static map<Function_t*,db_id_t> entry_points; + + +static void UpdateEntryPoints(std::map<db_id_t,Instruction_t*> &insnMap) +{ + /* for each function, look up the instruction that's the entry point */ + for( static map<Function_t*,db_id_t>::const_iterator it=entry_points.begin(); + it!=entry_points.end(); + ++it + ) + { + Function_t* func=(*it).first; + db_id_t func_entry_id=(*it).second; + + assert(insnMap[func_entry_id]); + func->SetEntryPoint(insnMap[func_entry_id]); + } + +} + +// Create a Variant from the database +FileIR_t::FileIR_t(const VariantID_t &newprogid, File_t* fid) : BaseObj_t(NULL) +{ + orig_variant_ir_p=NULL; + progid=newprogid; + + if(fid==NULL) + fileptr=newprogid.GetMainFile(); + else + fileptr=fid; + + if(progid.IsRegistered()) + ReadFromDB(); + +} + +// DB operations +void FileIR_t::ReadFromDB() +{ + entry_points.clear(); + + std::map<db_id_t,AddressID_t*> addrMap=ReadAddrsFromDB(); + std::map<db_id_t,Function_t*> funcMap=ReadFuncsFromDB(addrMap); + std::map<db_id_t,Instruction_t*> insnMap=ReadInsnsFromDB(funcMap,addrMap); + + UpdateEntryPoints(insnMap); +} + + +std::map<db_id_t,Function_t*> FileIR_t::ReadFuncsFromDB + ( + std::map<db_id_t,AddressID_t*> addrMap + ) +{ + std::map<db_id_t,Function_t*> idMap; + + std::string q= "select * from " + fileptr->function_table_name + " ; "; + + dbintr->IssueQuery(q); + + while(!dbintr->IsDone()) + { +// function_id | file_id | name | stack_frame_size | out_args_region_size | use_frame_pointer | doip_id + + db_id_t fid=atoi(dbintr->GetResultColumn("function_id").c_str()); + db_id_t entry_point_id=atoi(dbintr->GetResultColumn("entry_point_id").c_str()); + std::string name=dbintr->GetResultColumn("name"); + int sfsize=atoi(dbintr->GetResultColumn("stack_frame_size").c_str()); + int oasize=atoi(dbintr->GetResultColumn("out_args_region_size").c_str()); +// postgresql encoding of boolean can be 'true', '1', 'T', 'y' + bool useFP=false; + const char *useFPstr= dbintr->GetResultColumn("use_frame_pointer").c_str(); + if (strlen(useFPstr) > 0) + { + if (useFPstr[0] == 't' || useFPstr[0] == 'T' || useFPstr[0] == '1' || useFPstr[0] == 'y' || useFPstr[0] == 'Y') + useFP = true; + } + + db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); + + Function_t *newfunc=new Function_t(fid,name,sfsize,oasize,useFP,NULL); + entry_points[newfunc]=entry_point_id; + +//std::cout<<"Found function "<<name<<"."<<std::endl; + + idMap[fid]=newfunc; + + funcs.insert(newfunc); + + dbintr->MoveToNextRow(); + } + + return idMap; +} + + +std::map<db_id_t,AddressID_t*> FileIR_t::ReadAddrsFromDB + ( + ) +{ + std::map<db_id_t,AddressID_t*> idMap; + + std::string q= "select * from " + fileptr->address_table_name + " ; "; + + + dbintr->IssueQuery(q); + + while(!dbintr->IsDone()) + { +// address_id integer PRIMARY KEY, +// file_id integer REFERENCES file_info, +// vaddress_offset text, +// doip_id integer DEFAULT -1 + + + db_id_t aid=atoi(dbintr->GetResultColumn("address_id").c_str()); + db_id_t file_id=atoi(dbintr->GetResultColumn("file_id").c_str()); + int vaddr=atoi(dbintr->GetResultColumn("vaddress_offset").c_str()); + db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); + + AddressID_t *newaddr=new AddressID_t(aid,file_id,vaddr); + +//std::cout<<"Found address "<<aid<<"."<<std::endl; + + idMap[aid]=newaddr; + + addrs.insert(newaddr); + + dbintr->MoveToNextRow(); + } + + return idMap; +} + + +std::map<db_id_t,Instruction_t*> FileIR_t::ReadInsnsFromDB + ( + std::map<db_id_t,Function_t*> funcMap, + std::map<db_id_t,AddressID_t*> addrMap + ) +{ + std::map<db_id_t,Instruction_t*> idMap; + std::map<db_id_t,db_id_t> fallthroughs; + std::map<db_id_t,db_id_t> targets; + + std::string q= "select * from " + fileptr->instruction_table_name + " ; "; + + + dbintr->IssueQuery(q); + + while(!dbintr->IsDone()) + { + +// address_id integer REFERENCES #PROGNAME#_address, +// parent_function_id integer, +// orig_address_id integer REFERENCES #PROGNAME#_address, +// fallthrough_address_id integer, +// target_address_id integer, +// data bytea, +// callback text, +// comment text, +// doip_id integer DEFAULT -1 + + + db_id_t instruction_id=atoi(dbintr->GetResultColumn("instruction_id").c_str()); + db_id_t aid=atoi(dbintr->GetResultColumn("address_id").c_str()); + db_id_t parent_func_id=atoi(dbintr->GetResultColumn("parent_function_id").c_str()); + db_id_t orig_address_id=atoi(dbintr->GetResultColumn("orig_address_id").c_str()); + db_id_t fallthrough_address_id=atoi(dbintr->GetResultColumn("fallthrough_address_id").c_str()); + db_id_t targ_address_id=atoi(dbintr->GetResultColumn("target_address_id").c_str()); + std::string data=(dbintr->GetResultColumn("data")); + std::string callback=(dbintr->GetResultColumn("callback")); + std::string comment=(dbintr->GetResultColumn("comment")); + db_id_t indirect_branch_target_address_id = atoi(dbintr->GetResultColumn("ind_target_address_id").c_str()); + db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); + + std::string isIndStr=(dbintr->GetResultColumn("ind_target_address_id")); + + AddressID_t* indTarg = NULL; + if (indirect_branch_target_address_id != NOT_IN_DATABASE) + indTarg = addrMap[indirect_branch_target_address_id]; + + Instruction_t *newinsn=new Instruction_t(instruction_id, + addrMap[aid], + funcMap[parent_func_id], + orig_address_id, + data, callback, comment, indTarg, doipid); + + if(funcMap[parent_func_id]) + funcMap[parent_func_id]->GetInstructions().insert(newinsn); + +//std::cout<<"Found address "<<aid<<"."<<std::endl; + + idMap[instruction_id]=newinsn; + fallthroughs[instruction_id]=fallthrough_address_id; + targets[instruction_id]=targ_address_id; + + insns.insert(newinsn); + + dbintr->MoveToNextRow(); + } + + for(std::map<db_id_t,Instruction_t*>::const_iterator i=idMap.begin(); i!=idMap.end(); ++i) + { + Instruction_t *instr=(*i).second; + db_id_t fallthroughid=fallthroughs[instr->GetBaseID()]; + if(idMap[fallthroughid]) + instr->SetFallthrough(idMap[fallthroughid]); + db_id_t targetid=targets[instr->GetBaseID()]; + if(idMap[targetid]) + instr->SetTarget(idMap[targetid]); + } + + + return idMap; +} + + +void FileIR_t::WriteToDB() +{ + /* assign each item a unique ID */ + SetBaseIDS(); + + db_id_t j=-1; + + dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->instruction_table_name + string(" cascade;")); + dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->function_table_name + string(" cascade;")); + dbintr->IssueQuery(string("TRUNCATE TABLE ")+ fileptr->address_table_name + string(" cascade;")); + + /* and now that everything has an ID, let's write to the DB */ + string q=string(""); + for(std::set<Function_t*>::const_iterator i=funcs.begin(); i!=funcs.end(); ++i) + { + q+=(*i)->WriteToDB(fileptr,j); + if(q.size()>1024*1024) + { + dbintr->IssueQuery(q); + q=string(""); + } + + } + dbintr->IssueQuery(q); + + q=string(""); + for(std::set<AddressID_t*>::const_iterator i=addrs.begin(); i!=addrs.end(); ++i) + { + q+=(*i)->WriteToDB(fileptr,j); + if(q.size()>1024*1024) + { + dbintr->IssueQuery(q); + q=string(""); + } + } + dbintr->IssueQuery(q); + + q=string(""); + for(std::set<Instruction_t*>::const_iterator i=insns.begin(); i!=insns.end(); ++i) + { + q+=(*i)->WriteToDB(fileptr,j); + if(q.size()>1024*1024) + { + dbintr->IssueQuery(q); + q=string(""); + } + } + dbintr->IssueQuery(q); +} + + + +void FileIR_t::SetBaseIDS() +{ +#define MAX(a,b) (((a)>(b)) ? (a) : (b)) + + /* find the highest database ID */ + db_id_t j=0; + for(std::set<Function_t*>::const_iterator i=funcs.begin(); i!=funcs.end(); ++i) + j=MAX(j,(*i)->GetBaseID()); + for(std::set<AddressID_t*>::const_iterator i=addrs.begin(); i!=addrs.end(); ++i) + j=MAX(j,(*i)->GetBaseID()); + for(std::set<Instruction_t*>::const_iterator i=insns.begin(); i!=insns.end(); ++i) + j=MAX(j,(*i)->GetBaseID()); + + /* increment past the max ID so we don't duplicate */ + j++; + + /* for anything that's not yet in the DB, assign an ID to it */ + for(std::set<Function_t*>::const_iterator i=funcs.begin(); i!=funcs.end(); ++i) + if((*i)->GetBaseID()==NOT_IN_DATABASE) + (*i)->SetBaseID(j++); + for(std::set<AddressID_t*>::const_iterator i=addrs.begin(); i!=addrs.end(); ++i) + if((*i)->GetBaseID()==NOT_IN_DATABASE) + (*i)->SetBaseID(j++); + for(std::set<Instruction_t*>::const_iterator i=insns.begin(); i!=insns.end(); ++i) + if((*i)->GetBaseID()==NOT_IN_DATABASE) + (*i)->SetBaseID(j++); +} -- GitLab