diff --git a/include/zipr_dollop_man.h b/include/zipr_dollop_man.h index 7a466e5e1b80b302557f9b67b0d24e25e7d37906..3e3e71cff0d2e547fa6d1cd5e0a7446e5007541e 100644 --- a/include/zipr_dollop_man.h +++ b/include/zipr_dollop_man.h @@ -36,12 +36,25 @@ class ZiprDollopManager_t : public DollopManager_t { public: ZiprDollopManager_t() : m_refresh_stats(true) {} + + /* + * Adders. + */ void AddDollops(Dollop_t *dollop_head); Zipr_SDK::Dollop_t *AddNewDollops(libIRDB::Instruction_t *start); + + /* + * Getters. + */ Zipr_SDK::Dollop_t *GetContainingDollop(libIRDB::Instruction_t *insn); + size_t Size() { return m_dollops.size(); } + + /* + * Patch functions. + */ void AddDollopPatch(Zipr_SDK::DollopPatch_t *new_patch) { m_patches_to_dollops[new_patch->Target()].push_back(new_patch); } @@ -53,29 +66,51 @@ class ZiprDollopManager_t : public DollopManager_t { */ return m_patches_to_dollops.at(target); } - void PrintDollopPatches(const std::ostream &); + + /* + * Dollop target update functions. + */ bool UpdateTargets(Dollop_t *); void UpdateAllTargets(); + + /* + * Iteration functions. + */ std::list<Dollop_t*>::const_iterator dollops_begin() { return m_dollops.begin(); } std::list<Dollop_t*>::const_iterator dollops_end() { return m_dollops.end(); } - friend std::ostream &operator<<(std::ostream &out, const ZiprDollopManager_t &dollop_man); + + /* + * Printing/output functions. + */ + void PrintDollopPatches(const std::ostream &); + friend std::ostream &operator<<(std::ostream &out, + const ZiprDollopManager_t &dollop_man); void PrintStats(std::ostream &out); void PrintPlacementMap(const MemorySpace_t &memory_space, const std::string &map_filename); private: + /* + * Helper functions. + */ void AddDollop(Dollop_t *dollop); void CalculateStats(); + /* + * Support variables. + */ std::list<Dollop_t*> m_dollops; std::map<libIRDB::Instruction_t*,Dollop_t*> m_insn_to_dollop; std::list<DollopPatch_t*> m_patches; std::map<Dollop_t*, std::list<DollopPatch_t*>> m_patches_to_dollops; - bool m_refresh_stats; + /* + * Statistics. + */ + bool m_refresh_stats; size_t m_total_dollop_space, m_total_dollop_entries; unsigned int m_total_dollops, m_truncated_dollops; }; diff --git a/src/dollop.cpp b/src/dollop.cpp index 7661d96e779edbc5758063d929b2bc82e6cb3aa2..226d5d7da1b68aa4ffb235ec1f02a0bf818c9247 100644 --- a/src/dollop.cpp +++ b/src/dollop.cpp @@ -7,6 +7,7 @@ namespace Zipr_SDK { Dollop_t::Dollop_t(Instruction_t *start) : m_size(0), m_fallthrough_dollop(NULL), + m_fallback_dollop(NULL), m_fallthrough_patched(false), m_coalesced(false), m_was_truncated(false) @@ -96,6 +97,18 @@ namespace Zipr_SDK { new_dollop = new Dollop_t(); + /* + * Set fallthrough and fallback dollop pointers. + * ----- ---- + * | | | | + * this - new - fallthrough + * | + * |----- + */ + if (m_fallthrough_dollop) + m_fallthrough_dollop->FallbackDollop(new_dollop); + new_dollop->FallbackDollop(this); + new_dollop->FallthroughDollop(m_fallthrough_dollop); m_fallthrough_dollop = new_dollop; @@ -162,13 +175,15 @@ namespace Zipr_SDK { } std::ostream &operator<<(std::ostream &out, const Dollop_t &d) { std::list<DollopEntry_t*>::const_iterator it, it_end; - Dollop_t *fallthrough = NULL; + Dollop_t *fallthrough = NULL, *fallback = NULL; for (it = d.begin(), it_end = d.end(); it != it_end; it++) { out << std::hex << *(*it) << std::endl; } + if ((fallback = d.FallbackDollop()) != NULL) + out << "Fallback: " << std::hex << fallback << std::endl; if ((fallthrough = d.FallthroughDollop()) != NULL) out << "Fallthrough: " << std::hex << fallthrough << std::endl; return out; diff --git a/src/zipr_dollop_man.cpp b/src/zipr_dollop_man.cpp index 89dd43f29c2c462c27de5a616f8301292f7a4b55..665c7e88298724d21ea046c2c007abd1c8fc3fc2 100644 --- a/src/zipr_dollop_man.cpp +++ b/src/zipr_dollop_man.cpp @@ -73,6 +73,7 @@ namespace zipr { * the updated fallthrough dollop! */ new_dollop->FallthroughDollop(fallthrough_dollop); + fallthrough_dollop->FallbackDollop(new_dollop); /* * Delete the overlapping instructions. @@ -116,6 +117,7 @@ namespace zipr { { assert(existing_dollop->front()->Instruction() == fallthrough); new_dollop->FallthroughDollop(existing_dollop); + existing_dollop->FallbackDollop(new_dollop); break; } /* @@ -125,6 +127,7 @@ namespace zipr { previous_dollop = new_dollop; new_dollop = Dollop_t::CreateNewDollop(fallthrough); previous_dollop->FallthroughDollop(new_dollop); + new_dollop->FallbackDollop(previous_dollop); } AddDollops(original_new_dollop); return original_new_dollop; diff --git a/test/ZiprDollop.cpp b/test/ZiprDollop.cpp index d14b51368d56e69df115393bf289d5c79b345f70..1f6ce7cbe7087fa6adaa1fe4da9d17231890ccc6 100644 --- a/test/ZiprDollop.cpp +++ b/test/ZiprDollop.cpp @@ -180,7 +180,9 @@ bool TestAddNewDollopSplitsExistingDollop(void) { return success && a->GetDollopEntryCount() == 2 && b->GetDollopEntryCount() == 2 && - dollop_man.Size() == 2; + dollop_man.Size() == 2 && + a->FallthroughDollop() == b && + b->FallbackDollop() == a; } bool TestUpdateTargetsDollopManager(void) { @@ -349,7 +351,8 @@ bool TestDollopSplit(void) { cout << "Dollop B: " << endl; cout << *b << endl; - return a->GetDollopEntryCount() == 1 && b->GetDollopEntryCount() == 4; + return a->GetDollopEntryCount() == 1 && b->GetDollopEntryCount() == 4 && + a->FallthroughDollop() == b && b->FallbackDollop() == a; } bool TestDollopEntryEquals(void) {