diff --git a/include/zipr_dollop_man.h b/include/zipr_dollop_man.h
index 73ceaf3be5c62f606bae43be074deaf80716825c..fa14cb8efbe9538a844140285d792a28af02b3e4 100644
--- a/include/zipr_dollop_man.h
+++ b/include/zipr_dollop_man.h
@@ -64,6 +64,8 @@ class ZiprDollopManager_t {
 		}
 		friend std::ostream &operator<<(std::ostream &out, const ZiprDollopManager_t &dollop_man);
 		void PrintStats(std::ostream &out);
+		void PrintPlacementMap(const ZiprMemorySpace_t &memory_space,
+		                       const std::string &map_filename);
 	private:
 		void AddDollop(Dollop_t *dollop);
 		void CalculateStats();
diff --git a/include/zipr_mem_space.h b/include/zipr_mem_space.h
index 00fb766fb1563fd3fb730e720181ad6380831697..ccc70966af97b434bacc5e572ea12c6205d7f647 100644
--- a/include/zipr_mem_space.h
+++ b/include/zipr_mem_space.h
@@ -36,7 +36,11 @@ class ZiprMemorySpace_t : public MemorySpace_t
 {
 	public:
 		ZiprMemorySpace_t() :
-			free_ranges(), max_plopped(0), min_plopped(-1), m_verbose("verbose")
+			free_ranges(),
+			original_free_ranges(),
+			max_plopped(0),
+			min_plopped(-1),
+			m_verbose("verbose")
 		{ 
 		}
 
@@ -50,6 +54,7 @@ class ZiprMemorySpace_t : public MemorySpace_t
 		std::pair<RangeSet_t::const_iterator,RangeSet_t::const_iterator>
 			GetNearbyFreeRanges(const RangeAddress_t hint, size_t count = 0);
 		void AddFreeRange(Range_t newRange);
+		void AddFreeRange(Range_t newRange, bool original);
 		void RemoveFreeRange(Range_t newRange);
 		Range_t GetLargeRange(void);
 
@@ -59,6 +64,7 @@ class ZiprMemorySpace_t : public MemorySpace_t
 		bool IsValidRange(RangeSet_t::iterator it);
 
 		int GetRangeCount();
+		RangeSet_t GetOriginalFreeRanges() const { return original_free_ranges; }
 
 		void PrintMemorySpace(std::ostream &out);
 
@@ -92,6 +98,7 @@ class ZiprMemorySpace_t : public MemorySpace_t
 
 	protected:
 		RangeSet_t  free_ranges; // keep ordered
+		RangeSet_t  original_free_ranges; // keep ordered
 		// std::set<Range_t, Range_tCompare> free_ranges;   // keep ordered
 
 	private:
diff --git a/src/memory_space.cpp b/src/memory_space.cpp
index 5a9ed3cded6074bb13da3cb7ce0f29c6b78b74d7..4d2465dc05b3a381c83760e1042a208c96d0d170 100644
--- a/src/memory_space.cpp
+++ b/src/memory_space.cpp
@@ -235,6 +235,15 @@ bool ZiprMemorySpace_t::IsByteFree(RangeAddress_t addr)
 	return false;
 }
 
+void ZiprMemorySpace_t::AddFreeRange(Range_t newRange, bool original)
+{
+	if (original)
+	{
+		original_free_ranges.insert(Range_t(newRange.GetStart(),newRange.GetEnd()));
+	}
+	AddFreeRange(newRange);
+}
+
 void ZiprMemorySpace_t::AddFreeRange(Range_t newRange)
 {
 	free_ranges.insert(Range_t(newRange.GetStart(), newRange.GetEnd()));
diff --git a/src/zipr.cpp b/src/zipr.cpp
index d9fd2b92ae93b218015aed5f77fc9415d21c28af..877abccefc221a5571c2469678fb2102c1829689 100644
--- a/src/zipr.cpp
+++ b/src/zipr.cpp
@@ -485,7 +485,7 @@ void ZiprImpl_t::FindFreeRanges(const std::string &name)
 			last_end=end;
 			if (m_verbose)
 				printf("Adding free range 0x%p to 0x%p\n", (void*)start,(void*)end);
-			memory_space.AddFreeRange(Range_t(start,end));
+			memory_space.AddFreeRange(Range_t(start,end), true);
 		}
 	}
 
@@ -533,7 +533,7 @@ void ZiprImpl_t::FindFreeRanges(const std::string &name)
 	}
 #endif
 
-	memory_space.AddFreeRange(Range_t(new_free_page,(RangeAddress_t)-1));
+	memory_space.AddFreeRange(Range_t(new_free_page,(RangeAddress_t)-1), true);
 	if (m_verbose)
 		printf("Adding (mysterious) free range 0x%p to EOF\n", (void*)new_free_page);
 	start_of_new_space=new_free_page;
@@ -2399,6 +2399,7 @@ void ZiprImpl_t::PrintStats()
 {
 	// do something like print stats as #ATTRIBUTES.
 	m_dollop_mgr.PrintStats(cout);
+	m_dollop_mgr.PrintPlacementMap(memory_space, "dollop.map");
 	m_stats->PrintStats(cout);
 
 	// and dump a map file of where we placed instructions.  maybe guard with an option.
diff --git a/src/zipr_dollop_man.cpp b/src/zipr_dollop_man.cpp
index ee2a9f000b349741f8604c6859dc52c0633d552f..bf61d38f6ae55a1613d616099500f4f71b4925b1 100644
--- a/src/zipr_dollop_man.cpp
+++ b/src/zipr_dollop_man.cpp
@@ -1,5 +1,6 @@
 #include <zipr_all.h>
 #include <iostream>
+#include <cstdlib>
 
 using namespace zipr;
 using namespace zipr::Utils;
@@ -282,4 +283,121 @@ namespace zipr {
 		PrintStat(out, "Truncated dollop fraction",
 			(double)m_truncated_dollops/(double)m_total_dollops);
 	}
+
+#define LINE_LENGTH 32
+#define PRINT_LINE_HEADER(x) \
+	map_output << endl << std::hex << (x) << ": ";
+
+	void ZiprDollopManager_t::PrintPlacementMap(
+		const ZiprMemorySpace_t &memory_space,
+		const std::string &map_filename)
+	{
+		RangeSet_t original_ranges = memory_space.GetOriginalFreeRanges();
+		RangeSet_t::const_iterator range_it, range_it_end;
+		ofstream map_output(map_filename.c_str(), std::ofstream::out);
+
+		if (!map_output.is_open())
+			return;
+		/*
+		 * Loop through the original ranges.
+		 */
+		for (range_it=original_ranges.begin(), range_it_end=original_ranges.end();
+		     range_it != range_it_end;
+				 range_it++)
+		{
+			/*
+			 * Now loop through the dollops and
+			 * record those contained in this range.
+			 */
+			list<Dollop_t*>::const_iterator dollop_it, dollop_it_end;
+			Range_t current_range = *range_it;
+			map<RangeAddress_t, Dollop_t*> dollops_in_range;
+			map<RangeAddress_t, Dollop_t*>::const_iterator dollops_in_range_it,
+			                                               dollops_in_range_end;
+			RangeAddress_t previous_dollop_end = 0;
+			Dollop_t *dollop_to_print = NULL;
+
+			for (dollop_it = m_dollops.begin(), dollop_it_end = m_dollops.end();
+			     dollop_it != dollop_it_end;
+					 dollop_it++)
+			{
+				Dollop_t *dollop = (*dollop_it);
+				if (current_range.GetStart() <= dollop->Place() &&
+				    current_range.GetEnd() >= dollop->Place())
+					dollops_in_range[dollop->Place()] = dollop;
+			}
+			
+			map_output << "==========" << endl;
+			map_output << "Range: 0x" << std::hex << current_range.GetStart()
+			           << " - 0x" << std::hex << current_range.GetEnd() 
+								 << endl;
+			
+			previous_dollop_end = current_range.GetStart();
+			unsigned byte_print_counter = 0;
+			for (dollops_in_range_it = dollops_in_range.begin(),
+			     dollops_in_range_end = dollops_in_range.end();
+			     dollops_in_range_it != dollops_in_range_end;
+					 dollops_in_range_it++)
+			{
+				dollop_to_print = (*dollops_in_range_it).second;
+				if (previous_dollop_end < dollop_to_print->Place())
+				{
+					for (unsigned i=0;i<(dollop_to_print->Place()-previous_dollop_end);i++)
+					{
+						if (!((byte_print_counter) % LINE_LENGTH)) 
+							PRINT_LINE_HEADER((current_range.GetStart()+byte_print_counter))
+						map_output << "_";
+						byte_print_counter++;
+					}
+#if 0
+					map_output << "0x" << std::hex << previous_dollop_end
+					           << " - 0x" <<std::hex <<(dollop_to_print->Place())
+					           << ": (" << std::dec 
+					           << (dollop_to_print->Place() - previous_dollop_end)
+					           << ") EMPTY" << endl;
+#endif
+				}
+				for (unsigned i=0;i<(dollop_to_print->GetSize());i++)
+				{
+					if (!((byte_print_counter) % LINE_LENGTH))
+						PRINT_LINE_HEADER((current_range.GetStart()+byte_print_counter))
+					map_output << "X";
+					byte_print_counter++;
+				}
+#if 0
+				map_output << "0x" << std::hex << dollop_to_print->Place()
+				           << " - 0x" << std::hex
+									 <<(dollop_to_print->Place()+dollop_to_print->GetSize())
+									 << ": (" << std::dec << dollop_to_print->GetSize()
+									 << ") "
+									 << endl;
+
+#endif
+				previous_dollop_end = dollop_to_print->Place() + 
+				                      dollop_to_print->GetSize();
+			}
+
+			if (dollop_to_print && current_range.GetEnd() != (RangeAddress_t)-1 &&
+			   (previous_dollop_end < current_range.GetEnd())) 
+			{
+				for (unsigned i=0;i<(current_range.GetEnd() - previous_dollop_end);i++)
+				{
+					if (!((byte_print_counter) % LINE_LENGTH))
+						PRINT_LINE_HEADER((current_range.GetStart()+byte_print_counter))
+					map_output << "_";
+					byte_print_counter++;
+				}
+#if 0
+				map_output << "0x" << std::hex << dollop_to_print->Place()
+				           << " - 0x" << std::hex
+				           <<(dollop_to_print->Place()+dollop_to_print->GetSize())
+				           << ": (" << std::dec 
+				           << (current_range.GetEnd() - previous_dollop_end)
+				           << ") EMPTY" << endl;
+#endif
+			}
+			map_output << endl;
+		}
+		map_output.close();
+	}
 }