From ed4a24539f932585fd96a4f467162dabfac77bd9 Mon Sep 17 00:00:00 2001 From: whh8b <whh8b@git.zephyr-software.com> Date: Wed, 4 May 2016 03:00:02 +0000 Subject: [PATCH] Debug support for plugins to plop instructions. --- include/zipr_dollop_man.h | 10 ++++++++- include/zipr_impl.h | 23 +++++++++++++++++--- src/dollop.cpp | 24 +++++++++++++++----- src/zipr.cpp | 46 +++++++++++++++++++++++++++++++-------- src/zipr_dollop_man.cpp | 11 ++++++++-- test/SConscript | 2 +- 6 files changed, 95 insertions(+), 21 deletions(-) diff --git a/include/zipr_dollop_man.h b/include/zipr_dollop_man.h index e532497..b24fbce 100644 --- a/include/zipr_dollop_man.h +++ b/include/zipr_dollop_man.h @@ -41,7 +41,8 @@ typedef std::map<Dollop_t*, DollopPatchList_t > DollopToDollopPatchListMap_t; class ZiprDollopManager_t : public DollopManager_t { public: - ZiprDollopManager_t() : m_refresh_stats(true) {} + ZiprDollopManager_t() : m_refresh_stats(true), m_zipr(NULL) {} + ZiprDollopManager_t(Zipr_SDK::Zipr_t *zipr) : m_refresh_stats(true), m_zipr(zipr) {} /* * Adders. @@ -98,6 +99,11 @@ class ZiprDollopManager_t : public DollopManager_t { void PrintStats(std::ostream &out); void PrintPlacementMap(const MemorySpace_t &memory_space, const std::string &map_filename); + + /* + * Helper functions. + */ + int DetermineWorstCaseInsnSize(libIRDB::Instruction_t *insn); private: /* * Helper functions. @@ -119,5 +125,7 @@ class ZiprDollopManager_t : public DollopManager_t { bool m_refresh_stats; size_t m_total_dollop_space, m_total_dollop_entries; unsigned int m_total_dollops, m_truncated_dollops; + + Zipr_SDK::Zipr_t *m_zipr; }; #endif diff --git a/include/zipr_impl.h b/include/zipr_impl.h index d8b4ff4..44363c6 100644 --- a/include/zipr_impl.h +++ b/include/zipr_impl.h @@ -43,6 +43,7 @@ class ZiprImpl_t : public Zipr_t m_stats(NULL), m_firp(NULL), m_error(false), + m_dollop_mgr(this), elfiop(new ELFIO::elfio), start_of_new_space(0), memory_space(), @@ -57,7 +58,6 @@ class ZiprImpl_t : public Zipr_t m_architecture("architecture"), m_seed("seed", 0), m_dollop_map_filename("dollop_map_filename", "dollop.map") - { Init(); }; @@ -67,7 +67,24 @@ class ZiprImpl_t : public Zipr_t bool Error() { return m_error; } + /* + * PluginDetermineWorstCaseInsnSize + * + * Determine the worst case instruction 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); + /* + * DetermineWorstCaseInsnSize + * + * Determine the worst case instruction size + * but do not account for the possibility that a plugin + * may be plopping this instruction and want + * to do some calculations. + */ int DetermineWorstCaseInsnSize(libIRDB::Instruction_t*, bool account_for_jump = true); Zipr_SDK::RangeAddress_t PlopDollopEntry( @@ -216,6 +233,7 @@ class ZiprImpl_t : public Zipr_t void WriteDollops(); void UpdatePins(); + void ReplopDollopEntriesWithTargets(); /* * OptimizePinnedFallthrough() * @@ -426,8 +444,7 @@ class ZiprImpl_t : public Zipr_t ZiprIntegerOption_t m_variant, m_architecture, m_seed; ZiprStringOption_t m_dollop_map_filename; - - + std::list<DollopEntry_t *> m_des_to_replop; }; #endif diff --git a/src/dollop.cpp b/src/dollop.cpp index e4070ec..636bbbf 100644 --- a/src/dollop.cpp +++ b/src/dollop.cpp @@ -4,13 +4,14 @@ namespace Zipr_SDK { using namespace libIRDB; using namespace zipr; - Dollop_t::Dollop_t(Instruction_t *start) : + Dollop_t::Dollop_t(Instruction_t *start, Zipr_SDK::DollopManager_t *mgr) : m_size(0), m_fallthrough_dollop(NULL), m_fallback_dollop(NULL), m_fallthrough_patched(false), m_coalesced(false), - m_was_truncated(false) + m_was_truncated(false), + m_dollop_mgr(mgr) { Instruction_t *loop = NULL; @@ -40,7 +41,13 @@ namespace Zipr_SDK { it++) { Instruction_t *cur_insn = (*it)->Instruction(); - dollop_size += Utils::DetermineWorstCaseInsnSize(cur_insn, false); + if (m_dollop_mgr != NULL) + dollop_size += m_dollop_mgr->DetermineWorstCaseInsnSize(cur_insn); + else + { + assert(false); + dollop_size += Utils::DetermineWorstCaseInsnSize(cur_insn, false); + } } if ((m_fallthrough_dollop || (back() && @@ -97,6 +104,8 @@ namespace Zipr_SDK { new_dollop = new Dollop_t(); + new_dollop->SetDollopManager(m_dollop_mgr); + /* * Set fallthrough and fallback dollop pointers. * ----- ---- @@ -167,12 +176,16 @@ namespace Zipr_SDK { return comp.m_instruction == m_instruction && comp.m_target_dollop == m_target_dollop; } + bool DollopEntry_t::operator!=(const DollopEntry_t &comp) { return !operator==(comp); } - Dollop_t *Dollop_t::CreateNewDollop(libIRDB::Instruction_t *start) { - return new Zipr_SDK::Dollop_t(start); + + Dollop_t *Dollop_t::CreateNewDollop(libIRDB::Instruction_t *start, + Zipr_SDK::DollopManager_t *mgr) { + return new Zipr_SDK::Dollop_t(start, mgr); } + std::ostream &operator<<(std::ostream &out, const Dollop_t &d) { std::list<DollopEntry_t*>::const_iterator it, it_end; Dollop_t *fallthrough = NULL, *fallback = NULL; @@ -193,6 +206,7 @@ namespace Zipr_SDK { out << std::hex << &p << ":" << std::hex << p.Target(); return out; } + std::ostream &operator<<(std::ostream &out, const DollopEntry_t &p) { out << "Instruction: " << std::hex << p.Instruction() << std::endl; out << "Target Dollop: " << std::hex << p.TargetDollop() << std::endl; diff --git a/src/zipr.cpp b/src/zipr.cpp index 6f9b462..5d8f08b 100644 --- a/src/zipr.cpp +++ b/src/zipr.cpp @@ -339,6 +339,8 @@ void ZiprImpl_t::CreateBinaryFile() WriteDollops(); + ReplopDollopEntriesWithTargets(); + UpdatePins(); // tell plugins we are done plopping and about to link callbacks. @@ -1337,10 +1339,26 @@ void ZiprImpl_t::WriteDollops() end = _PlopDollopEntry(entry_to_write); should_end = start + _DetermineWorstCaseInsnSize(entry_to_write->Instruction(), false); assert(end <= should_end); + if (entry_to_write->TargetDollop()) + m_des_to_replop.push_back(entry_to_write); } } } +void ZiprImpl_t::ReplopDollopEntriesWithTargets() +{ + for (DollopEntry_t *entry_to_write : m_des_to_replop) + { + Instruction_t *src_insn = NULL; + RangeAddress_t src_insn_addr; + + src_insn = entry_to_write->Instruction(); + + src_insn_addr = final_insn_locations[src_insn]; + PlopDollopEntry(entry_to_write, src_insn_addr); + } +} + void ZiprImpl_t::PlaceDollops() { int count_pins=0; @@ -1695,12 +1713,6 @@ void ZiprImpl_t::PlaceDollops() m_stats->total_did_not_coalesce++; - /* - * Since we inserted a new instruction, we should - * check to see whether a plugin wants to plop it. - */ - AskPluginsAboutPlopping(patch_de->Instruction()); - /* * Quit the do-while-true loop that is placing * as many dollops in-a-row as possible. @@ -1859,6 +1871,11 @@ void ZiprImpl_t::PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr) } } +int ZiprImpl_t::PluginDetermineWorstCaseInsnSize(Instruction_t *insn, bool account_for_jump) +{ + return (int)_DetermineWorstCaseInsnSize(insn, account_for_jump); +} + size_t ZiprImpl_t::_DetermineWorstCaseInsnSize(Instruction_t* insn, bool account_for_jump) { std::map<Instruction_t*,DLFunctionHandle_t>::const_iterator plop_it; @@ -1881,7 +1898,6 @@ size_t ZiprImpl_t::_DetermineWorstCaseInsnSize(Instruction_t* insn, bool account return worst_case_size; } -//static int DetermineWorstCaseInsnSize(Instruction_t* insn) int ZiprImpl_t::DetermineWorstCaseInsnSize(Instruction_t* insn, bool account_for_jump) { return Utils::DetermineWorstCaseInsnSize(insn, account_for_jump); @@ -1944,6 +1960,9 @@ void ZiprImpl_t::UpdatePins() patch_addr = p.GetAddress(); target_addr = target_dollop_entry->Place(); + if (final_insn_locations.end() != final_insn_locations.find(target_dollop_entry->Instruction())) + target_addr = final_insn_locations[target_dollop_entry->Instruction()]; + if (plugman.DoesPluginRetargetPin(patch_addr, target_dollop, target_addr, patcher)) { if (m_verbose) @@ -1962,6 +1981,9 @@ void ZiprImpl_t::UpdatePins() */ target_addr = target_dollop_entry->Place(); + if (final_insn_locations.end() != final_insn_locations.find(target_dollop_entry->Instruction())) + target_addr = final_insn_locations[target_dollop_entry->Instruction()]; + if (m_verbose) cout << "Patching pin at " << std::hex << patch_addr << " to " << std::hex << target_addr << ": " << d.CompleteInstr << endl; @@ -2114,11 +2136,17 @@ RangeAddress_t ZiprImpl_t::PlopDollopEntry( if(entry->TargetDollop()) { + RangeAddress_t target_address = 0; + Instruction_t *target_insn = entry->TargetDollop()->front()->Instruction(); + + if (final_insn_locations.end() != final_insn_locations.find(target_insn)) + target_address = final_insn_locations[target_insn]; + if (m_verbose) cout << "Plopping at " << std::hex << addr - << " with target " << std::hex << entry->TargetDollop()->Place() + << " with target " << std::hex << ((target_address != 0) ? target_address : entry->TargetDollop()->Place()) << endl; - ret=PlopDollopEntryWithTarget(entry, addr); + ret=PlopDollopEntryWithTarget(entry, addr, target_address); } else if(entry->Instruction()->GetCallback()!="") { diff --git a/src/zipr_dollop_man.cpp b/src/zipr_dollop_man.cpp index 9752f06..a1cb1ee 100644 --- a/src/zipr_dollop_man.cpp +++ b/src/zipr_dollop_man.cpp @@ -45,7 +45,7 @@ namespace zipr { std::list<DollopEntry_t*>::iterator it, it_end; Dollop_t *original_new_dollop = NULL, *previous_dollop = NULL; Instruction_t *fallthrough = NULL; - original_new_dollop = new_dollop = Dollop_t::CreateNewDollop(start); + original_new_dollop = new_dollop = Dollop_t::CreateNewDollop(start,this); for (it = new_dollop->begin(), it_end = new_dollop->end(); it != it_end; @@ -125,7 +125,7 @@ namespace zipr { * and link them together. */ previous_dollop = new_dollop; - new_dollop = Dollop_t::CreateNewDollop(fallthrough); + new_dollop = Dollop_t::CreateNewDollop(fallthrough, this); previous_dollop->FallthroughDollop(new_dollop); new_dollop->FallbackDollop(previous_dollop); } @@ -134,6 +134,13 @@ namespace zipr { } } + int ZiprDollopManager_t::DetermineWorstCaseInsnSize(libIRDB::Instruction_t *insn) { + if (m_zipr != NULL) + return m_zipr->PluginDetermineWorstCaseInsnSize(insn, false); + else + return Utils::DetermineWorstCaseInsnSize(insn, false); + } + void ZiprDollopManager_t::PrintDollopPatches(const ostream &out) { std::list<DollopPatch_t*>::const_iterator patch_it, patch_it_end; diff --git a/test/SConscript b/test/SConscript index 2585952..05fef64 100644 --- a/test/SConscript +++ b/test/SConscript @@ -76,6 +76,6 @@ Range=myenv.Program("Range.exe", Split(RangeFiles)) MemorySpace=myenv.Program("MemorySpace.exe", Split(MemorySpaceFiles)) Options=myenv.Program("Options.exe", Split(OptionFiles)) Dollop=myenv.Program("Dollop.exe", Split(DollopFiles)) -Default([MemorySpace, Options, Dollop, Range]) +Default([MemorySpace, Options, Range]) #Default([Range]) -- GitLab