diff --git a/libIRDB/include/core/eh.hpp b/libIRDB/include/core/eh.hpp index 5ad9741831fd7365d5b994f4b3b3f85b6ee9ff36..f720847133c2bcbfe67de817f2e9b4fbdfd96cbe 100644 --- a/libIRDB/include/core/eh.hpp +++ b/libIRDB/include/core/eh.hpp @@ -71,16 +71,16 @@ class EhProgram_t : public BaseObj_t bool operator<(const EhProgram_t&a, const EhProgram_t&b); typedef std::set<EhProgram_t*> EhProgramSet_t; +typedef std::vector<int> TTOrderVector_t; class EhCallSite_t : public BaseObj_t { public: - EhCallSite_t(const db_id_t id, const uint64_t enc=0, Instruction_t* lp=NULL, const bool &p_has_cleanup=false) : + EhCallSite_t(const db_id_t id, const uint64_t enc=0, Instruction_t* lp=NULL) : BaseObj_t(NULL), tt_encoding(enc), - landing_pad(lp), - has_cleanup(p_has_cleanup) + landing_pad(lp) { SetBaseID(id); } uint64_t GetTTEncoding() const { return tt_encoding; } @@ -89,8 +89,11 @@ class EhCallSite_t : public BaseObj_t Instruction_t* GetLandingPad() const { return landing_pad; } void SetLandingPad(Instruction_t* lp) { landing_pad=lp; } - bool GetHasCleanup() const { return has_cleanup; } - void SetHasCleanup(bool p_has_cleanup=true) { has_cleanup=p_has_cleanup; } + bool GetHasCleanup() const ; + void SetHasCleanup(bool p_has_cleanup=true) ; + + TTOrderVector_t& GetTTOrderVector() { return ttov; } + const TTOrderVector_t& GetTTOrderVector() const { return ttov; } std::string WriteToDB(File_t* fid); // writes to DB, ID is not -1. @@ -98,7 +101,7 @@ class EhCallSite_t : public BaseObj_t uint64_t tt_encoding; Instruction_t* landing_pad; - bool has_cleanup; + TTOrderVector_t ttov; }; typedef std::set<EhCallSite_t*> EhCallSiteSet_t; diff --git a/libIRDB/src/core/eh.cpp b/libIRDB/src/core/eh.cpp index 3ef8b8ac8bc3ff7d2700590072b4cb9f612c1f72..036b94eda4d9ed4f968369d9a64b390dbeba45a5 100644 --- a/libIRDB/src/core/eh.cpp +++ b/libIRDB/src/core/eh.cpp @@ -110,18 +110,56 @@ std::string EhProgram_t::WriteToDB(File_t* fid) // writes to DB, ID is not -1 std::string EhCallSite_t::WriteToDB(File_t* fid) // writes to DB, ID is not -1. { + const auto vec_to_string=[](const vector<int> &v) + { + stringstream s; + for(const auto &e : v) + { + s<<dec<<e<<" "; + } + + return s.str(); + }; string q; + + auto landing_pad_id=BaseObj_t::NOT_IN_DATABASE; if(landing_pad != NULL) landing_pad_id=landing_pad->GetBaseID(); + const auto ttov_str=vec_to_string(ttov); + q ="insert into " + fid->GetEhCallSiteTableName(); - q+="(ehcs_id,tt_encoding,has_cleanup,lp_insn_id) "+ + q+="(ehcs_id,tt_encoding,ttov,lp_insn_id) "+ string(" VALUES (") + string("'") + to_string(GetBaseID()) + string("', ") + string("'") + to_string(+tt_encoding) + string("', ") + - string("'") + to_string(+has_cleanup) + string("', ") + + string("'") + ttov_str + string("', ") + string("'") + to_string(landing_pad_id) + string("') ;"); return q; } + +bool EhCallSite_t::GetHasCleanup() const +{ + const auto ttov_it=find(ttov.begin(), ttov.end(), 0); + return ttov_it!=ttov.end(); +} + +void EhCallSite_t::SetHasCleanup(bool p_has_cleanup) +{ + if(p_has_cleanup) + { + if(!GetHasCleanup()) + ttov.push_back(0); + } + else + { + if(GetHasCleanup()) + { + const auto ttov_it=find(ttov.begin(), ttov.end(), 0); + ttov.erase(ttov_it); + } + } +} + diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index b3a5742e9c39b25e8dda0f985e9ebb5f52d0c6e4..81a505d0b7ce2723a800bd502f99527dd1a044ea 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -362,6 +362,15 @@ std::map<db_id_t,EhCallSite_t*> FileIR_t::ReadEhCallSitesFromDB 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. @@ -371,10 +380,11 @@ std::map<db_id_t,EhCallSite_t*> FileIR_t::ReadEhCallSitesFromDB 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 has_cleanup=(bool)atoi(dbintr->GetResultColumn("has_cleanup").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, has_cleanup); // create the call site with an unresolved LP + 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) diff --git a/libIRDB/test/split_eh_frame.cpp b/libIRDB/test/split_eh_frame.cpp index 6eb041d512a725e52b4739ac94fdd2a202e9f008..276550f43cdfe6ad9647664d85c7ac8da841593f 100644 --- a/libIRDB/test/split_eh_frame.cpp +++ b/libIRDB/test/split_eh_frame.cpp @@ -1123,6 +1123,9 @@ class lsda_type_table_entry_t: private eh_frame_util_t<ptrsize> ) { tt_encoding=p_tt_encoding; + const auto tt_encoding_sans_indirect = tt_encoding&(~DW_EH_PE_indirect); + const auto tt_encoding_sans_indir_sans_pcrel = tt_encoding_sans_indirect & (~DW_EH_PE_pcrel); + const auto has_pcrel = (tt_encoding & DW_EH_PE_pcrel) == DW_EH_PE_pcrel; switch(tt_encoding & 0xf) // get just the size field { case DW_EH_PE_udata4: @@ -1132,10 +1135,15 @@ class lsda_type_table_entry_t: private eh_frame_util_t<ptrsize> default: assert(0); } + const auto orig_act_pos=uint32_t(tt_pos+(-index*tt_encoding_size)); auto act_pos=uint32_t(tt_pos+(-index*tt_encoding_size)); - if(this->read_type_with_encoding(tt_encoding, pointer_to_typeinfo, act_pos, data, max, data_addr)) + if(this->read_type_with_encoding(tt_encoding_sans_indir_sans_pcrel, pointer_to_typeinfo, act_pos, data, max, data_addr)) return true; + // check if there's a 0 in the field + if(pointer_to_typeinfo != 0 && has_pcrel) + pointer_to_typeinfo += orig_act_pos + data_addr; + return false; } @@ -1300,6 +1308,7 @@ class lsda_call_site_t : private eh_frame_util_t<ptrsize> for_each(action_table.begin(), action_table.end(), [&](const lsda_call_site_action_t<ptrsize>& p) { const auto action=p.GetAction(); + new_ehcs->GetTTOrderVector().push_back(action); if(action==0) { // NO! This means that the type table has a 0, which means catch all. @@ -1463,8 +1472,7 @@ class lsda_t : private eh_frame_util_t<ptrsize> for(int i=1;i<=max_tt_entry;i++) { lsda_type_table_entry_t <ptrsize> ltte; - auto type_table_encoding_sans_indirect = type_table_encoding&(~DW_EH_PE_indirect); - if(ltte.parse(type_table_encoding_sans_indirect, type_table_pos, i, data, max, data_addr )) + if(ltte.parse(type_table_encoding, type_table_pos, i, data, max, data_addr )) return true; type_table.push_back(ltte); } @@ -1836,7 +1844,7 @@ class split_eh_frame_impl_t : public split_eh_frame_t cout<<hex<<insn->GetAddress()->GetVirtualOffset()<<":" <<insn->GetBaseID()<<":"<<insn->getDisassembly()<<" -> "<<endl; //fie_it->GetCIE().print(); - //fie_it->print(); + fie_it->print(); } const auto fde_addr=fie_it->GetFDEStartAddress();