From dfd6b36c59430c12450b7c46beab33e14f82b99a Mon Sep 17 00:00:00 2001
From: whh8b <whh8b@git.zephyr-software.com>
Date: Thu, 21 Jan 2016 01:43:38 +0000
Subject: [PATCH] Make sure that we do not replop any parts of dollops.

This is important for a number of reasons.
Most importantly, however, is the fact that it
will cause a problem with the push64 relocations
calculations.
---
 src/zipr_dollop_man.cpp | 55 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/src/zipr_dollop_man.cpp b/src/zipr_dollop_man.cpp
index 9216b3d..52e0828 100644
--- a/src/zipr_dollop_man.cpp
+++ b/src/zipr_dollop_man.cpp
@@ -41,18 +41,73 @@ namespace zipr {
 			/*
 			 * There is no target dollop. Let's create one!
 			 */
+			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);
 
+			for (it = new_dollop->begin(), it_end = new_dollop->end();
+			     it != it_end;
+					 it++)
+			{
+				Dollop_t *containing_dollop = GetContainingDollop((*it)->Instruction());
+				if (containing_dollop) 
+				{
+					Dollop_t *fallthrough_dollop = NULL;
+					if (true)
+						cout << "Found an instruction in a new dollop that "
+						     << "is already in a dollop: " << std::hex
+								 << (*it)->Instruction()->GetAddress()->GetVirtualOffset()
+								 << endl;
+					/*
+					 * Delete the overlapping instructions.
+					 */
+					new_dollop->erase(it, it_end);
+
+					/*
+					 * Reliably get a pointer to the containing dollop.
+					 */
+					fallthrough_dollop = AddNewDollops((*it)->Instruction());
+
+					/*
+					 * Link this dollop to that one.
+					 */
+					new_dollop->FallthroughDollop(fallthrough_dollop);
+
+					/*
+					 * Put the new dollop in!
+					 */
+					AddDollop(new_dollop);
+
+					return new_dollop;
+				}
+			}
+			/*
+			 * This is to handle the case where
+			 * we stopped creating a dollop because
+			 * the next instruction is pinned. We do
+			 * not want to forget about the remaining
+			 * entries here. So, we attempt to link
+			 * to those, where possible.
+			 */
 			while (fallthrough = new_dollop->back()->Instruction()->GetFallthrough())
 			{
 				/*
 				 * Look FIRST for a containing dollop.
+				 *
+				 * TODO: We *assert* that we do not have
+				 * to check whether or not the fallthrough
+				 * instruction is at the top of the stack.
+				 * This is because we are only at this case
+				 * when the dollop construction ended because
+				 * the fallthrough is pinned. This implicitly
+				 * means that it is the first instruction
+				 * in the containing dollop.
 				 */
 				Dollop_t *existing_dollop = GetContainingDollop(fallthrough);
 				if (existing_dollop)
 				{
+					assert(existing_dollop->front()->Instruction() == fallthrough);
 					new_dollop->FallthroughDollop(existing_dollop);
 					break;
 				}
-- 
GitLab