Newer
Older
/*
* Copyright (c) 2014 - Zephyr Software LLC
*
* 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 Zephyr
* Software.
*
* 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: Zephyr Software
* e-mail: jwd@zephyr-software.com
* URL : http://www.zephyr-software.com/
*
*/
#include <cstdlib>
#include <fstream>
#include <stdlib.h>
#include <sys/wait.h>

Jason Hiser
committed
#include "cmdstr.hpp"
#define SCOOP_CHUNK_SIZE (10*1024*1024) /* 10 mb */
#define ALLOF(a) begin(a),end(a)
int command_to_stream(const string& command, ostream& stream)
{

Jason Hiser
committed
const auto res = command_to_string(command);

Jason Hiser
committed
stream << res.first << endl;
return res.second;
static void UpdateEntryPoints(
const std::map<db_id_t,Instruction_t*> &insnMap,
const map<Function_t*,db_id_t>& entry_points)
{
/* for each function, look up the instruction that's the entry point */
for( 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(func_entry_id==-1 || insnMap.at(func_entry_id));
func->setEntryPoint(insnMap.at(func_entry_id));
// cout<<"Function named "<<func->getName()<< " getting entry point set to "<<insnMap[func_entry_id]->getComment()<<"."<<endl;
static void UpdateUnresolvedEhCallSites(
const std::map<db_id_t,Instruction_t*> &insnMap,
const std::map<EhCallSite_t*,db_id_t> & unresolvedEhcss)
{
for(const auto &i : unresolvedEhcss)
{
const auto& ehcs=i.first;
const auto& insnid=i.second;
const auto& insn=insnMap.at(insnid);
assert(insn);
}
}
static virtual_offset_t strtovo(std::string s)
return IRDB_SDK::strtoint<virtual_offset_t>(s);
FileIR_t::FileIR_t(const VariantID_t &newprogid, File_t* fid)
: BaseObj_t(NULL), progid((VariantID_t&) newprogid)
fileptr=dynamic_cast<File_t*>(newprogid.getMainFile());
FileIR_t::~FileIR_t()
{
for(auto i : funcs ) delete i;
for(auto i : insns ) delete i;
for(auto i : addrs ) delete i;
for(auto i : relocs) delete i;
for(auto i : types ) delete i;
auto entry_points=map<Function_t*,db_id_t>();
auto unresolvedICFS=std::map<Instruction_t*, db_id_t>();
auto unresolvedEhCallSites=std::map<EhCallSite_t*,db_id_t>();
auto objMap=std::map<db_id_t,BaseObj_t*>();
auto addressToInstructionMap=std::map<db_id_t,Instruction_t*>();
auto ehpgmMap = ReadEhPgmsFromDB();
auto ehcsMap = ReadEhCallSitesFromDB(unresolvedEhCallSites);
auto typesMap = ReadTypesFromDB(types);
auto addrMap = ReadAddrsFromDB();
auto funcMap = ReadFuncsFromDB(addrMap, typesMap,entry_points);
auto scoopMap = ReadScoopsFromDB(addrMap, typesMap);
auto insnMap = ReadInsnsFromDB(funcMap,addrMap,ehpgmMap,ehcsMap,addressToInstructionMap, unresolvedICFS);
ReadAllICFSFromDB(addressToInstructionMap, unresolvedICFS);
jdh8d
committed
// put the scoops, instructions, ehpgms, eh call sites into the object map.
// if relocs end up on other objects, we'll need to add them to. for now only these things.
objMap.insert(insnMap.begin(), insnMap.end());
objMap.insert(scoopMap.begin(), scoopMap.end());
objMap.insert(ehcsMap.begin(), ehcsMap.end());
jdh8d
committed
objMap.insert(ehpgmMap.begin(), ehpgmMap.end());
ReadRelocsFromDB(objMap);
UpdateEntryPoints(insnMap,entry_points);
UpdateUnresolvedEhCallSites(insnMap,unresolvedEhCallSites);
void FileIR_t::changeRegistryKey(IRDB_SDK::Instruction_t *p_orig, IRDB_SDK::Instruction_t *p_updated)
auto orig=dynamic_cast<libIRDB::Instruction_t*>(p_orig);
auto updated=dynamic_cast<libIRDB::Instruction_t*>(p_updated);
if(assembly_registry.find(orig) != assembly_registry.end())
{
assembly_registry[updated] = assembly_registry[orig];
assembly_registry.erase(orig);
}
}
{
if(assembly_registry.size() == 0)
return;
string assemblyFile = "tmp.asm";
string binaryOutputFile = "tmp.bin";
string command = "rm -f " + assemblyFile + " " + binaryOutputFile;
auto actual_exit = command_to_stream(command, cout); // system(command.c_str());
assert(actual_exit == 0);
ofstream asmFile;
asmFile.open(assemblyFile.c_str());
if(!asmFile.is_open())
assert(false);
asmFile<<"BITS "<<std::dec<<getArchitectureBitWidth()<<endl;
}
asmFile.close();
command = string("nasm ") + assemblyFile + string(" -o ") + binaryOutputFile;
actual_exit = command_to_stream(command,cout); // system(command.c_str());
assert(actual_exit == 0);
ifstream binreader;
unsigned int filesize;
binreader.open(binaryOutputFile.c_str(),ifstream::in|ifstream::binary);
assert(binreader.is_open());
binreader.seekg(0,ios::end);
filesize = binreader.tellg();
binreader.seekg(0,ios::beg);
unsigned char *binary_stream = new unsigned char[filesize];
binreader.read((char*)binary_stream,filesize);
binreader.close();
unsigned int index = 0;
registry_type::iterator reg_val = assembly_registry.begin();
while(index < filesize)
{
//the number of registered instructions should not be exceeded
assert(reg_val != assembly_registry.end());
Instruction_t *instr = reg_val->first;
// disasm.EIP = (UIntPtr)&binary_stream[index];
// int instr_len = Disasm(&disasm);
const auto p_disasm=DecodedInstruction_t::factory
(
/* fake start addr doesn't matter */0x1000,
(void*)&binary_stream[index],
(void*)&binary_stream[filesize]
);
assert(disasm.valid());
const auto instr_len=disasm.length();
string rawBits;
rawBits.resize(instr_len);
for(auto i=0U;i<instr_len;i++,index++)
{
rawBits[i] = binary_stream[index];
}
instr->setDataBits(rawBits);
// *verbose_logging << "doing instruction:" << ((Instruction_t*)instr)->getDisassembly() << " comment: " << ((Instruction_t*)instr)->getComment() << endl;
reg_val++;
assert(reg_val == assembly_registry.end());
delete [] binary_stream;
assembly_registry.clear();
}
void FileIR_t::registerAssembly(IRDB_SDK::Instruction_t *p_instr, string assembly)
auto instr=dynamic_cast<Instruction_t*>(p_instr);
assert(instr);
assembly_registry[instr] = assembly;
}
void FileIR_t::unregisterAssembly(IRDB_SDK::Instruction_t *p_instr)
auto instr=dynamic_cast<Instruction_t*>(p_instr);
assert(instr);
assembly_registry.erase(instr);
}
std::string FileIR_t::lookupAssembly(IRDB_SDK::Instruction_t *p_instr)
auto instr=dynamic_cast<Instruction_t*>(p_instr);
assert(instr);
if (assembly_registry.find(instr) != assembly_registry.end())
return assembly_registry[instr];
else
return std::string();
}
std::map<db_id_t,Function_t*> FileIR_t::ReadFuncsFromDB
(
std::map<db_id_t,AddressID_t*> &addrMap,
std::map<db_id_t,Type_t*> &typesMap,
map<Function_t*,db_id_t> &entry_points
auto idMap=std::map<db_id_t,Function_t*> ();
auto q=std::string("select * from ") + fileptr->function_table_name + " ; ";
// function_id | file_id | name | stack_frame_size | out_args_region_size | use_frame_pointer | is_safe | 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());
db_id_t function_type_id=atoi(dbintr->getResultColumn("type_id").c_str());
// postgresql encoding of boolean can be 'true', '1', 'T', 'y'
string useFPString=dbintr->getResultColumn("use_frame_pointer");
string isSafeString=dbintr->getResultColumn("is_safe");
const char *useFPstr=useFPString.c_str();
const char *isSafestr=isSafeString.c_str();
if (strlen(useFPstr) > 0)
{
if (useFPstr[0] == 't' || useFPstr[0] == 'T' || useFPstr[0] == '1' || useFPstr[0] == 'y' || useFPstr[0] == 'Y')
useFP = true;
}
if (strlen(isSafestr) > 0)
{
if (isSafestr[0] == 't' || isSafestr[0] == 'T' || isSafestr[0] == '1' || isSafestr[0] == 'y' || isSafestr[0] == 'Y')
isSafe = true;
}
//db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str());
FuncType_t* fnType = NULL;
if (typesMap.count(function_type_id) > 0)
fnType = dynamic_cast<FuncType_t*>(typesMap[function_type_id]);
Function_t *newfunc=new Function_t(fid,name,sfsize,oasize,useFP,isSafe,fnType, NULL);
entry_points[newfunc]=entry_point_id;
//std::cout<<"Found function "<<name<<"."<<std::endl;
idMap[fid]=newfunc;
funcs.insert(newfunc);
std::map<db_id_t,EhCallSite_t*> FileIR_t::ReadEhCallSitesFromDB
(
map<EhCallSite_t*,db_id_t> &unresolvedEhCssLandingPads // output arg.
)
{
auto ehcsMap=std::map<db_id_t,EhCallSite_t*>();
std::string q= "select * from " + fileptr->getEhCallSiteTableName() + " ; ";
for(dbintr->issueQuery(q); !dbintr->isDone(); dbintr->moveToNextRow())
{
const auto string_to_vec=[&](const string& str ) -> vector<int>
{
auto out=vector<int>();
istringstream s(str);
auto in=(int)0;
while ( s >> in)
out.push_back(in);
return out;
};
/*
* ehcs_id integer, -- id of this object.
* tt_encoding integer, -- the encoding of the type table.
* lp_insn_id integer -- the landing pad instruction's id.
*/
const auto eh_cs_id=atoi(dbintr->getResultColumn("ehcs_id").c_str());
const auto tt_encoding=atoi(dbintr->getResultColumn("tt_encoding").c_str());
const auto &ttov=string(dbintr->getResultColumn("ttov").c_str());
const auto lp_insn_id=atoi(dbintr->getResultColumn("lp_insn_id").c_str());
auto newEhCs=new EhCallSite_t(eh_cs_id,tt_encoding,NULL); // create the call site with an unresolved LP
newEhCs->GetTTOrderVector()=string_to_vec(ttov);
eh_css.insert(newEhCs); // record that it exists.
ehcsMap[eh_cs_id]=newEhCs; // record the map for when we read instructions.
if(lp_insn_id != BaseObj_t::NOT_IN_DATABASE)
unresolvedEhCssLandingPads[newEhCs]=lp_insn_id; // note that the LP is unresolved
}
return ehcsMap;
}
std::map<db_id_t,EhProgram_t*> FileIR_t::ReadEhPgmsFromDB()
{
auto idMap = std::map<db_id_t,EhProgram_t*>();
auto q=std::string("select * from ") + fileptr->ehpgm_table_name + " ; ";
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
auto decode_pgm=[](const string& encoded_pgm, EhProgramListing_t& decoded_pgm)
{
auto split=[](const string& str, const string& delim, EhProgramListing_t& tokens) -> void
{
auto prev = size_t(0);
auto pos = size_t(0);
do
{
pos = str.find(delim, prev);
if (pos == string::npos) pos = str.length();
string token = str.substr(prev, pos-prev);
if (!token.empty()) tokens.push_back(token);
prev = pos + delim.length();
}
while (pos < str.length() && prev < str.length());
};
auto decode_in_place=[](string& to_decode) -> void
{
auto charToHex=[](uint8_t value) -> uint8_t
{
if (value >= '0' && value <= '9') return value - '0';
else if (value >= 'A' && value <= 'F') return value - 'A' + 10;
else if (value >= 'a' && value <= 'f') return value - 'a' + 10;
assert(false);
};
auto out=string("");
while(to_decode.size() > 0)
{
// to-decode should have pairs of characters that represent individual bytes.
assert(to_decode.size() >= 2);
auto val = uint8_t ( charToHex(to_decode[0])*16 + charToHex(to_decode[1]) );
out += val;
to_decode.erase(0,2);
}
to_decode=out;
};
split(encoded_pgm, ",", decoded_pgm);
// decode each one
for(auto& i : decoded_pgm)
decode_in_place(i);
};
{
/*
* eh_pgm_id integer,
* caf integer,
* daf integer,
* ptrsize integer,
* cie_program text,
* fde_program text
*/
const auto eh_pgm_id=atoi(dbintr->getResultColumn("eh_pgm_id").c_str());
const auto caf=atoi(dbintr->getResultColumn("caf").c_str());
const auto daf=atoi(dbintr->getResultColumn("daf").c_str());
const auto rr=atoi(dbintr->getResultColumn("return_register").c_str());
const auto ptrsize=atoi(dbintr->getResultColumn("ptrsize").c_str());
const auto& encoded_cie_program = dbintr->getResultColumn("cie_program");
const auto& encoded_fde_program = dbintr->getResultColumn("fde_program");
auto new_ehpgm=new EhProgram_t(eh_pgm_id, caf, daf, rr, ptrsize, {}, {});
decode_pgm(encoded_cie_program, new_ehpgm->GetCIEProgram());
decode_pgm(encoded_fde_program, new_ehpgm->GetFDEProgram());
idMap[eh_pgm_id]=new_ehpgm;
eh_pgms.insert(new_ehpgm);
}
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 + " ; ";
{
// address_id integer PRIMARY KEY,
// file_id integer REFERENCES file_info,
db_id_t aid=atoi(dbintr->getResultColumn("address_id").c_str());
db_id_t file_id=atoi(dbintr->getResultColumn("file_id").c_str());
virtual_offset_t vaddr=strtovo(dbintr->getResultColumn("vaddress_offset"));
//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);
static string encoded_to_raw_string(string encoded)
{
int len = encoded.length();
std::string raw;
for(int i=0; i< len; i+=2)
{
string byte = encoded.substr(i,2);
char chr = (char) (int)strtol(byte.c_str(), nullptr, 16);
raw.push_back(chr);
}
return raw;
}
std::map<db_id_t,Instruction_t*> FileIR_t::ReadInsnsFromDB
(
const std::map<db_id_t,Function_t*> &funcMap,
const std::map<db_id_t,AddressID_t*> &addrMap,
const std::map<db_id_t,EhProgram_t*> &ehpgmMap,
const std::map<db_id_t,EhCallSite_t*> &ehcsMap,
std::map<db_id_t,Instruction_t*> &addressToInstructionMap,
std::map<Instruction_t*, db_id_t> &unresolvedICFS
)
{
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 + " ; ";
{
// 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());
db_id_t icfs_id=atoi(dbintr->getResultColumn("icfs_id").c_str());
db_id_t eh_pgm_id=atoi(dbintr->getResultColumn("ehpgm_id").c_str());
db_id_t eh_cs_id=atoi(dbintr->getResultColumn("ehcss_id").c_str());
std::string encoded_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"));
auto indTarg=(AddressID_t*)NULL;
indTarg = addrMap.at(indirect_branch_target_address_id);
auto parent_func=(Function_t*)NULL;
if(parent_func_id!= NOT_IN_DATABASE) parent_func=funcMap.at(parent_func_id);
addrMap.at(aid),
parent_func,
orig_address_id,
data, callback, comment, indTarg, doipid);
if(eh_pgm_id != NOT_IN_DATABASE) newinsn->setEhProgram(ehpgmMap.at(eh_pgm_id));
if(eh_cs_id != NOT_IN_DATABASE) newinsn->setEhCallSite(ehcsMap.at(eh_cs_id));
if(parent_func)
parent_func->GetInstructions().insert(newinsn);
newinsn->setFunction(funcMap.at(parent_func_id));
//std::cout<<"Found address "<<aid<<"."<<std::endl;
idMap[instruction_id]=newinsn;
fallthroughs[instruction_id]=fallthrough_address_id;
targets[instruction_id]=targ_address_id;
}
else
{
// keep track of instructions for which we have not yet
// resolved the ICFS
unresolvedICFS[newinsn] = icfs_id;
}
}
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()];
instr->setFallthrough(idMap[fallthroughid]);
db_id_t targetid=targets[instr->getBaseID()];
std::map<db_id_t,BaseObj_t*> &objMap
)
{
std::string q= "select * from " + fileptr->relocs_table_name + " ; ";
db_id_t reloc_id=atoi(dbintr->getResultColumn("reloc_id").c_str());
int reloc_offset=atoi(dbintr->getResultColumn("reloc_offset").c_str());
std::string reloc_type=(dbintr->getResultColumn("reloc_type"));
db_id_t instruction_id=atoi(dbintr->getResultColumn("instruction_id").c_str());
//db_id_t doipid=atoi(dbintr->getResultColumn("doip_id").c_str());
db_id_t wrt_id=atoi(dbintr->getResultColumn("wrt_id").c_str());
uint32_t addend=atoi(dbintr->getResultColumn("addend").c_str());
Relocation_t *reloc=new Relocation_t(reloc_id,reloc_offset,reloc_type,wrt_obj,addend);
assert(objMap[instruction_id]!=NULL);
objMap[instruction_id]->GetRelocations().insert(reloc);
void FileIR_t::writeToDB(ostream *verbose_logging)
// const auto WriteIRDB_start = clock();
const auto pqIntr=dynamic_cast<pqxxDB_t*>(dbintr);
assert(pqIntr);
//Resolve (assemble) any instructions in the registry.
CleanupICFS(verbose_logging);
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->instruction_table_name + string(" cascade;"));
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->icfs_table_name + string(" cascade;"));
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->icfs_map_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;"));
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->relocs_table_name + string(" cascade;"));
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->types_table_name + string(" cascade;"));
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->scoop_table_name + string(" cascade;"));
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->scoop_table_name+"_part2"+ string(" cascade;"));
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->ehpgm_table_name + string(" cascade;"));
dbintr->issueQuery(string("TRUNCATE TABLE ")+ fileptr->ehcss_table_name + string(" cascade;"));
/* and now that everything has an ID, let's write to the DB */
for(auto t=types.begin(); t!=types.end(); ++t)
auto real_t=dynamic_cast<Type_t*>(*t);
assert(real_t);
q+=real_t->WriteToDB(fileptr,j); // @TODO: wtf is j?
if(q.size()>1024*1024)
{
for(auto f=funcs.begin(); f!=funcs.end(); ++f)
auto real_f=dynamic_cast<Function_t*>(*f);
assert(real_f);
q+=real_f->WriteToDB(fileptr,j);
pqxx::tablewriter W_addrs(pqIntr->getTransaction(),fileptr->address_table_name);
auto real_a=dynamic_cast<AddressID_t*>(a);
assert(real_a);
W_addrs << real_a->WriteToDB(fileptr,j,withHeader);
pqxx::tablewriter W(pqIntr->getTransaction(),fileptr->instruction_table_name);
for(auto i=insns.begin(); i!=insns.end(); ++i)
auto insnp=dynamic_cast<Instruction_t*>(*i);
//DISASM disasm;
//Disassemble(insnp,disasm);
const auto p_disasm=DecodedInstruction_t::factory(insnp);
const auto& disasm=*p_disasm;
if(insnp->getOriginalAddressID() == NOT_IN_DATABASE)
// if(insnp->getFallthrough()==NULL && disasm.Instruction.BranchType!=RetType && disasm.Instruction.BranchType!=JmpType )
if(insnp->getFallthrough()==NULL && !disasm.isReturn() && !disasm.isUnconditionalBranch())
{
// instructions that fall through are required to either specify a fallthrough that's
// 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.
*verbose_logging << "NULL fallthrough: offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->getComment() << endl;
//if(insnp->getTarget()==NULL && disasm.Instruction.BranchType!=0 &&
// disasm.Instruction.BranchType!=RetType &&
// // not an indirect branch
// ((disasm.Instruction.BranchType!=JmpType && disasm.Instruction.BranchType!=CallType) ||
// disasm.Argument1.ArgType&CONSTANT_TYPE))
if(insnp->getTarget()==NULL && disasm.isBranch() && !disasm.isReturn() &&
( (!disasm.isUnconditionalBranch() && !disasm.isCall()) || disasm.getOperand(0)->isConstant())
// direct branches are required to either specify a target that's
// 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.
*verbose_logging << "Call must have a target; offending instruction:" << ((Instruction_t*)insnp)->getDisassembly() << " comment: " << ((Instruction_t*)insnp)->getComment() << endl;
const auto &insn_values=insnp->WriteToDB(fileptr,j);
for (auto it = GetAllICFS().begin(); it != GetAllICFS().end(); ++it)
assert(icfs);
string q = icfs->WriteToDB(fileptr);
for(auto it=scoops.begin(); it!=scoops.end(); ++it)
DataScoop_t* scoop = dynamic_cast<DataScoop_t*>(*it);
pqxx::tablewriter W_eh(pqIntr->getTransaction(),fileptr->ehpgm_table_name);
for(const auto& i : eh_pgms)
W_eh << dynamic_cast<EhProgram_t*>(i)->WriteToDB(fileptr);
}
W_eh.complete();
// eh css
for(const auto& i : eh_css)
{
string q = dynamic_cast<EhCallSite_t*>(i)->WriteToDB(fileptr);
dbintr->issueQuery(q);
jdh8d
committed
pqxx::tablewriter W_reloc(pqIntr->getTransaction(),fileptr->relocs_table_name);
// eh css relocs
for(const auto& i : eh_css)
{

Jason Hiser
committed
for(auto& reloc : relocs)
W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i));
}
{

Jason Hiser
committed
for(auto& reloc : relocs)
W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i));
}

Jason Hiser
committed
for(auto& reloc : relocs)
W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i));
}
// write out instruction's relocs
for(const auto& i : insns)
{

Jason Hiser
committed
for(auto& reloc : relocs)
W_reloc << dynamic_cast<Relocation_t*>(reloc)->WriteToDB(fileptr,dynamic_cast<BaseObj_t*>(i));
{
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
/* find the highest database ID */
db_id_t j=0;
for(auto i=funcs.begin(); i!=funcs.end(); ++i)
for(auto i=addrs.begin(); i!=addrs.end(); ++i)
for(auto i=insns.begin(); i!=insns.end(); ++i)
for(auto i=relocs.begin(); i!=relocs.end(); ++i)
for(auto i=types.begin(); i!=types.end(); ++i)
for(auto i=scoops.begin(); i!=scoops.end(); ++i)
for(auto i=icfs_set.begin(); i!=icfs_set.end(); ++i)
for(auto i=eh_pgms.begin(); i!=eh_pgms.end(); ++i)
for(auto i=eh_css.begin(); i!=eh_css.end(); ++i)
return j+1; // easy to off-by-one this so we do it for a user just in case.
}
{
/* 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(auto i=funcs.begin(); i!=funcs.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
for(auto i=addrs.begin(); i!=addrs.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
for(auto i=insns.begin(); i!=insns.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
for(auto i=relocs.begin(); i!=relocs.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
for(auto i=types.begin(); i!=types.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
for(auto i=scoops.begin(); i!=scoops.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
for(auto i=icfs_set.begin(); i!=icfs_set.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
for(auto i=eh_pgms.begin(); i!=eh_pgms.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
for(auto i=eh_css.begin(); i!=eh_css.end(); ++i)
if((*i)->getBaseID()==NOT_IN_DATABASE)
(*i)->setBaseID(j++);
const IRDB_SDK::ArchitectureDescription_t* IRDB_SDK::FileIR_t::getArchitecture()
{
return libIRDB::FileIR_t::archdesc;
}
uint32_t IRDB_SDK::FileIR_t::getArchitectureBitWidth()
return libIRDB::FileIR_t::archdesc->getBitWidth();
void FileIR_t::setArchitecture(const int width, const ADMachineType_t mt)
{
if(archdesc==NULL)
archdesc=new ArchitectureDescription_t;
archdesc->setFileBase(0); // maybe not rght for PE files?
}
{
/* the first 16 bytes of an ELF file define the magic number and ELF Class. */
// unsigned char e_ident[16];
union
{
Elf32_Ehdr ehdr32;
Elf64_Ehdr ehdr64;
} hdr_union;
auto myinter=BaseObj_t::GetInterface();
auto *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter);
const auto elfoid=getFile()->getELFOID();
pqxx::largeobjectaccess loa(mypqxxintr->getTransaction(), elfoid, PGSTD::ios::in);
loa.cread((char*)&hdr_union, sizeof(hdr_union));
const auto e_ident=hdr_union.ehdr32.e_ident;
libIRDB::FileIR_t::archdesc=new ArchitectureDescription_t;
if((e_ident[EI_MAG0]==ELFMAG0) &&
(e_ident[EI_MAG1]==ELFMAG1) &&