From 22bfeab41c142a9875fbee5ae180c280b0a95173 Mon Sep 17 00:00:00 2001 From: whh8b <whh8b@git.zephyr-software.com> Date: Mon, 27 Jun 2016 17:19:34 +0000 Subject: [PATCH] Several changes: 1. Update semantics of how plugins determine the size and space of the dollop that they will plop. 2. Add sorting for plugin invocation based on lexigraphical sorting. --- include/plugin_man.h | 4 +- include/zipr_dollop_man.h | 2 +- include/zipr_impl.h | 11 ++-- include/zipr_utils.h | 2 +- src/dollop.cpp | 2 +- src/plugin_man.cpp | 28 ++++++-- src/utils.cpp | 2 +- src/zipr.cpp | 135 +++++++++++++++++++++++++------------- src/zipr_dollop_man.cpp | 6 +- 9 files changed, 129 insertions(+), 63 deletions(-) diff --git a/include/plugin_man.h b/include/plugin_man.h index 58f464c4b..f32de9ab7 100644 --- a/include/plugin_man.h +++ b/include/plugin_man.h @@ -2,7 +2,7 @@ #define plugin_man_h typedef Zipr_SDK::ZiprPluginInterface_t* DLFunctionHandle_t; -typedef std::set<DLFunctionHandle_t> DLFunctionHandleSet_t; +typedef std::vector<DLFunctionHandle_t> DLFunctionHandleSet_t; typedef Zipr_SDK::ZiprPluginInterface_t* (*GetPluginInterface_t)( Zipr_SDK::Zipr_t* @@ -43,7 +43,7 @@ class ZiprPluginManager_t : public ZiprPluginInterface_t virtual RangeAddress_t PlaceScoopsBegin(const RangeAddress_t max_addr); virtual RangeAddress_t PlaceScoopsEnd(const RangeAddress_t max_addr); - virtual bool DoesPluginPlop(libIRDB::Instruction_t*,DLFunctionHandle_t&); + virtual bool DoPluginsPlop(libIRDB::Instruction_t*,std::list<DLFunctionHandle_t>&); virtual bool DoesPluginAddress(const Dollop_t *, const RangeAddress_t &, Range_t &, bool &coalesce, DLFunctionHandle_t &); virtual bool DoesPluginRetargetCallback(const RangeAddress_t &, const DollopEntry_t *, RangeAddress_t &, DLFunctionHandle_t &) ; diff --git a/include/zipr_dollop_man.h b/include/zipr_dollop_man.h index b24fbce40..f50d01cef 100644 --- a/include/zipr_dollop_man.h +++ b/include/zipr_dollop_man.h @@ -103,7 +103,7 @@ class ZiprDollopManager_t : public DollopManager_t { /* * Helper functions. */ - int DetermineWorstCaseInsnSize(libIRDB::Instruction_t *insn); + size_t DetermineWorstCaseDollopEntrySize(DollopEntry_t *entry); private: /* * Helper functions. diff --git a/include/zipr_impl.h b/include/zipr_impl.h index 6018b6609..40f7c58cf 100644 --- a/include/zipr_impl.h +++ b/include/zipr_impl.h @@ -69,14 +69,14 @@ class ZiprImpl_t : public Zipr_t return m_error; } /* - * PluginDetermineWorstCaseInsnSize + * DetermineWorstCaseDollopEntrySize * - * Determine the worst case instruction size + * Determine the worst case dollop entry size. * and account for the possibility that a plugin * may be plopping this instruction and want * to do some calculations. */ - int PluginDetermineWorstCaseInsnSize(libIRDB::Instruction_t *insn, bool account_for_jump = true); + size_t DetermineWorstCaseDollopEntrySize(DollopEntry_t *entry, bool account_for_jump = true); /* * DetermineWorstCaseInsnSize @@ -86,7 +86,7 @@ class ZiprImpl_t : public Zipr_t * may be plopping this instruction and want * to do some calculations. */ - int DetermineWorstCaseInsnSize(libIRDB::Instruction_t*, bool account_for_jump = true); + size_t DetermineWorstCaseInsnSize(libIRDB::Instruction_t*, bool account_for_jump = true); Zipr_SDK::RangeAddress_t PlopDollopEntry( DollopEntry_t *, @@ -469,7 +469,8 @@ class ZiprImpl_t : public Zipr_t ZiprPluginManager_t plugman; - std::map<libIRDB::Instruction_t*,DLFunctionHandle_t> plopping_plugins; + std::map<libIRDB::Instruction_t*, + std::unique_ptr<std::list<DLFunctionHandle_t>>> plopping_plugins; // Options ZiprOptions_t m_zipr_options; diff --git a/include/zipr_utils.h b/include/zipr_utils.h index d5c5769ee..0345e1901 100644 --- a/include/zipr_utils.h +++ b/include/zipr_utils.h @@ -8,7 +8,7 @@ namespace Utils { extern size_t LONG_PIN_SIZE; extern size_t SHORT_PIN_SIZE; void PrintStat(std::ostream &out, std::string description, double value); - int DetermineWorstCaseInsnSize(libIRDB::Instruction_t*, bool account_for_jump = true); + size_t DetermineWorstCaseInsnSize(libIRDB::Instruction_t*, bool account_for_jump = true); /** \brief Calculate entire size of a dollop * and it's fallthroughs. diff --git a/src/dollop.cpp b/src/dollop.cpp index 477010329..23160aed9 100644 --- a/src/dollop.cpp +++ b/src/dollop.cpp @@ -47,7 +47,7 @@ namespace Zipr_SDK { { Instruction_t *cur_insn = (*it)->Instruction(); if (m_dollop_mgr != NULL) - dollop_size += m_dollop_mgr->DetermineWorstCaseInsnSize(cur_insn); + dollop_size += m_dollop_mgr->DetermineWorstCaseDollopEntrySize(*it); else { assert(false); diff --git a/src/plugin_man.cpp b/src/plugin_man.cpp index 8f928bae0..7d67996db 100644 --- a/src/plugin_man.cpp +++ b/src/plugin_man.cpp @@ -59,6 +59,20 @@ for(DLFunctionHandleSet_t::iterator it=m_handleList.begin(); it!=m_handleList.en ZiprPluginInterface_t* zpi=(ZiprPluginInterface_t*)*it; \ var=zpi->func(var); \ } + +/* + * sort_plugins_by_name() + * + * Use this function as the comparator for sorting + * the plugins by the name that they return in their + * ToString() method. Sorting plugins by name is + * useful when trying to debug problems that depend + * on specific ordering. + */ +bool sort_plugins_by_name(DLFunctionHandle_t a, DLFunctionHandle_t b) +{ + return a->ToString() < b->ToString(); +} void ZiprPluginManager_t::PinningBegin() { @@ -118,19 +132,20 @@ bool ZiprPluginManager_t::DoesPluginAddress(const Dollop_t *dollop, const RangeA return false; } -bool ZiprPluginManager_t::DoesPluginPlop(Instruction_t *insn, DLFunctionHandle_t &callback) +bool ZiprPluginManager_t::DoPluginsPlop(Instruction_t *insn, std::list<DLFunctionHandle_t> &callbacks) { + bool a_plugin_does_plop = false; DLFunctionHandleSet_t::iterator it=m_handleList.begin(); for(m_handleList.begin();it!=m_handleList.end();++it) { ZiprPluginInterface_t* zpi=(ZiprPluginInterface_t*)*it; if (zpi->WillPluginPlop(insn)) { - callback = zpi; - return true; + callbacks.push_back(zpi); + a_plugin_does_plop = true; } } - return false; + return a_plugin_does_plop; } bool ZiprPluginManager_t::DoesPluginRetargetCallback(const RangeAddress_t &callback_addr, const DollopEntry_t *callback_entry, RangeAddress_t &target_address, DLFunctionHandle_t &patcher) @@ -231,9 +246,12 @@ void ZiprPluginManager_t::open_plugins } p_opts->AddNamespace(interface->RegisterOptions(global_ns)); - m_handleList.insert(interface); + m_handleList.push_back(interface); } closedir(dp); + + std::sort(m_handleList.begin(), m_handleList.end(), sort_plugins_by_name); + return; } diff --git a/src/utils.cpp b/src/utils.cpp index c4bb3fd29..cbe612aa6 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -53,7 +53,7 @@ size_t DetermineWorstCaseDollopSizeInclFallthrough(Dollop_t *dollop) return fallthroughs_wcds; } -int DetermineWorstCaseInsnSize(Instruction_t* insn, bool account_for_jump) +size_t DetermineWorstCaseInsnSize(Instruction_t* insn, bool account_for_jump) { int required_size=0; diff --git a/src/zipr.cpp b/src/zipr.cpp index 7ad5b60b9..7856220d0 100644 --- a/src/zipr.cpp +++ b/src/zipr.cpp @@ -1413,7 +1413,7 @@ void ZiprImpl_t::WriteDollops() start = entry_to_write->Place(); end = _PlopDollopEntry(entry_to_write); - should_end = start + _DetermineWorstCaseInsnSize(entry_to_write->Instruction(), false); + should_end = start + DetermineWorstCaseDollopEntrySize(entry_to_write, false); assert(end <= should_end); /* * Build up a list of those dollop entries that we have @@ -1537,7 +1537,7 @@ void ZiprImpl_t::PlaceDollops() to_place->ReCalculateWorstCaseSize(); minimum_valid_req_size = std::min( - _DetermineWorstCaseInsnSize(to_place->front()->Instruction()), + DetermineWorstCaseDollopEntrySize(to_place->front()), Utils::DetermineWorstCaseDollopSizeInclFallthrough(to_place)); /* * Ask the plugin manager if there are any plugins @@ -1842,11 +1842,11 @@ void ZiprImpl_t::PlaceDollops() bool last_de_fits = false; bool disallowed_override = true; de_and_fallthrough_fit = (placement.GetEnd()>= /* fits */ - (cur_addr+_DetermineWorstCaseInsnSize(dollop_entry->Instruction())) + (cur_addr+DetermineWorstCaseDollopEntrySize(dollop_entry)) ); last_de_fits = (std::next(dit,1)==dit_end) /* last */ && (placement.GetEnd()>=(cur_addr+ /* fits */ - _DetermineWorstCaseInsnSize(dollop_entry->Instruction(), + DetermineWorstCaseDollopEntrySize(dollop_entry, to_place->FallthroughDollop()!=NULL)) /* with or without fallthrough */ ); @@ -1860,8 +1860,8 @@ void ZiprImpl_t::PlaceDollops() all_fallthroughs_fit && ((placement.GetEnd() - (cur_addr + - _DetermineWorstCaseInsnSize( - dollop_entry->Instruction(), + DetermineWorstCaseDollopEntrySize( + dollop_entry, false) ) < Utils::TRAMPOLINE_SIZE ) @@ -1903,7 +1903,7 @@ void ZiprImpl_t::PlaceDollops() } #endif dollop_entry->Place(cur_addr); - cur_addr+=_DetermineWorstCaseInsnSize(dollop_entry->Instruction(), + cur_addr+=DetermineWorstCaseDollopEntrySize(dollop_entry, false); if (dollop_entry->TargetDollop()) { @@ -2035,9 +2035,8 @@ void ZiprImpl_t::PlaceDollops() /* * ... or maybe we just want to start the next dollop. */ - fallthrough_wcis = _DetermineWorstCaseInsnSize(fallthrough-> - front()-> - Instruction()); + fallthrough_wcis=DetermineWorstCaseDollopEntrySize(fallthrough-> + front()); remaining_size = placement.GetEnd() - cur_addr; /* @@ -2071,8 +2070,7 @@ void ZiprImpl_t::PlaceDollops() patch_de->TargetDollop(fallthrough); patch_de->Place(cur_addr); - cur_addr+=_DetermineWorstCaseInsnSize(patch_de->Instruction(), - false); + cur_addr+=DetermineWorstCaseDollopEntrySize(patch_de, false); to_place->push_back(patch_de); to_place->FallthroughPatched(true); @@ -2273,54 +2271,92 @@ void ZiprImpl_t::PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr) } } -int ZiprImpl_t::PluginDetermineWorstCaseInsnSize(Instruction_t *insn, bool account_for_jump) +size_t ZiprImpl_t::DetermineWorstCaseDollopEntrySize(DollopEntry_t *entry, bool account_for_jump) { - return (int)_DetermineWorstCaseInsnSize(insn, account_for_jump); + std::map<Instruction_t*,unique_ptr<list<DLFunctionHandle_t>>>::const_iterator plop_it; + size_t padding = 0; + size_t wcis = _DetermineWorstCaseInsnSize(entry->Instruction(), account_for_jump); + + plop_it = plopping_plugins.find(entry->Instruction()); + if (plop_it != plopping_plugins.end()) + { + for (auto handle : *(plop_it->second)) + { + ZiprPluginInterface_t *zpi = dynamic_cast<ZiprPluginInterface_t*>(handle); + padding += zpi->InsnPaddingSize(entry->Instruction(),this); + } + } + + if (m_verbose) + { + cout << "Adding padding of " << padding << "." << endl; + cout << "WCDES of " << std::hex << entry << ":" << std::dec << wcis+padding << endl; + } + + return wcis+padding; } size_t ZiprImpl_t::_DetermineWorstCaseInsnSize(Instruction_t* insn, bool account_for_jump) { - std::map<Instruction_t*,DLFunctionHandle_t>::const_iterator plop_it; + std::map<Instruction_t*,unique_ptr<list<DLFunctionHandle_t>>>::const_iterator plop_it; size_t worst_case_size = 0; + size_t default_worst_case_size = 0; + + default_worst_case_size = DetermineWorstCaseInsnSize(insn, account_for_jump); plop_it = plopping_plugins.find(insn); if (plop_it != plopping_plugins.end()) { - DLFunctionHandle_t handle = plop_it->second; - ZiprPluginInterface_t *zpi = dynamic_cast<ZiprPluginInterface_t*>(handle); - worst_case_size = zpi->WorstCaseInsnSize(insn,account_for_jump,this); + for (auto handle : *(plop_it->second)) + { + ZiprPluginInterface_t *zpi = dynamic_cast<ZiprPluginInterface_t*>(handle); + worst_case_size = std::max(zpi->WorstCaseInsnSize(insn, + account_for_jump, + this), + worst_case_size); + } } else - worst_case_size = DetermineWorstCaseInsnSize(insn, account_for_jump); + { + worst_case_size = default_worst_case_size; + } #if 1 if (m_verbose) - cout << "Worst case size" << ((account_for_jump) ? " (including jump)" : "") + cout << "Worst case size" + << ((account_for_jump) ? " (including jump)" : "") << ": " << worst_case_size << endl; #endif return worst_case_size; } -int ZiprImpl_t::DetermineWorstCaseInsnSize(Instruction_t* insn, bool account_for_jump) +size_t ZiprImpl_t::DetermineWorstCaseInsnSize(Instruction_t *insn, bool account_for_jump) { return Utils::DetermineWorstCaseInsnSize(insn, account_for_jump); } bool ZiprImpl_t::AskPluginsAboutPlopping(Instruction_t *insn) { - DLFunctionHandle_t plopping_plugin; - if (plugman.DoesPluginPlop(insn, plopping_plugin)) + /* + * Plopping plugins should hold a set. + */ + unique_ptr<list<DLFunctionHandle_t>> found_plopping_plugins = + unique_ptr<list<DLFunctionHandle_t>>(new std::list<DLFunctionHandle_t>()); + + if (plugman.DoPluginsPlop(insn, *found_plopping_plugins)) { - ZiprPluginInterface_t *zipr_plopping_plugin = - dynamic_cast<ZiprPluginInterface_t*>(plopping_plugin); if (m_verbose) - { - cout << zipr_plopping_plugin->ToString() - << " will plop "<<dec<<insn->GetBaseID() << ":" - << insn->getDisassembly() << endl; - } - plopping_plugins[insn] = plopping_plugin; + for (auto pp : *found_plopping_plugins) + { + ZiprPluginInterface_t *zipr_plopping_plugin = + dynamic_cast<ZiprPluginInterface_t*>(pp); + cout << zipr_plopping_plugin->ToString() + << " will plop "<<dec<<insn->GetBaseID() << ":" + << insn->getDisassembly() << endl; + } + + plopping_plugins[insn] = std::move(found_plopping_plugins); return true; } return false; @@ -2437,28 +2473,39 @@ void ZiprImpl_t::PatchInstruction(RangeAddress_t from_addr, Instruction_t* to_in RangeAddress_t ZiprImpl_t::_PlopDollopEntry(DollopEntry_t *entry, RangeAddress_t override_address) { Instruction_t *insn = entry->Instruction(); - RangeAddress_t addr = entry->Place(); - RangeAddress_t updated_addr; - std::map<Instruction_t*,DLFunctionHandle_t>::const_iterator plop_it; + size_t insn_wcis = _DetermineWorstCaseInsnSize(insn, false); + RangeAddress_t updated_addr = 0; + RangeAddress_t placed_address = entry->Place(); - if (override_address != 0) - addr = override_address; + map<Instruction_t*,unique_ptr<std::list<DLFunctionHandle_t>>>::const_iterator plop_it; + if (override_address != 0) + placed_address = override_address; + plop_it = plopping_plugins.find(insn); if (plop_it != plopping_plugins.end()) { - DLFunctionHandle_t handle = plop_it->second; - RangeAddress_t placed_address = 0; - ZiprPluginInterface_t *zpi = dynamic_cast<ZiprPluginInterface_t*>(handle); - updated_addr = zpi->PlopDollopEntry(entry, placed_address, this); - if (m_verbose) - cout << "Placed address: " << std::hex << placed_address << endl; + for (auto pp : *(plop_it->second)) + { + DLFunctionHandle_t handle = pp; + ZiprPluginInterface_t *zpi = dynamic_cast<ZiprPluginInterface_t*>(handle); + updated_addr = std::max(zpi->PlopDollopEntry(entry, + placed_address, + insn_wcis, + this), + updated_addr); + if (m_verbose) + cout << zpi->ToString() << " placed entry " + << std::hex << entry + << " at address: " << std::hex << placed_address + << endl; + } final_insn_locations[insn] = placed_address; } else { - final_insn_locations[insn] = addr; - updated_addr = PlopDollopEntry(entry, addr); + final_insn_locations[insn] = placed_address; + updated_addr = PlopDollopEntry(entry, placed_address); } return updated_addr; } diff --git a/src/zipr_dollop_man.cpp b/src/zipr_dollop_man.cpp index a1cb1ee9b..89e7b5b6c 100644 --- a/src/zipr_dollop_man.cpp +++ b/src/zipr_dollop_man.cpp @@ -134,11 +134,11 @@ namespace zipr { } } - int ZiprDollopManager_t::DetermineWorstCaseInsnSize(libIRDB::Instruction_t *insn) { + size_t ZiprDollopManager_t::DetermineWorstCaseDollopEntrySize(DollopEntry_t *entry) { if (m_zipr != NULL) - return m_zipr->PluginDetermineWorstCaseInsnSize(insn, false); + return m_zipr->DetermineWorstCaseDollopEntrySize(entry, false); else - return Utils::DetermineWorstCaseInsnSize(insn, false); + return Utils::DetermineWorstCaseInsnSize(entry->Instruction(), false); } void ZiprDollopManager_t::PrintDollopPatches(const ostream &out) { -- GitLab