diff --git a/P1_utility.cpp b/P1_utility.cpp
index 83d12539cc820df43ce9515e48a05b9bafda8851..a5ae1c13b65ac586bb823e496bf66b24b9fb3a83 100644
--- a/P1_utility.cpp
+++ b/P1_utility.cpp
@@ -34,8 +34,12 @@ Instruction_t* P1_insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, str
 	Instruction_t* newInsn = IRDB_SDK::insertAssemblyBefore(virp, first, assembly, target);
 	Function_t* func = newInsn->getFunction();
 	inserted_instr[func].insert(newInsn);
-        inserted_addr[func].insert(newInsn->getAddress());
-        return newInsn;
+    inserted_addr[func].insert(newInsn->getAddress());
+	if (verbose_log)
+	{
+		cout << "P1_insertAssemblyBefore is adding: " << assembly << endl;
+	}
+    return newInsn;
 }
 
 
@@ -45,7 +49,11 @@ Instruction_t* P1_insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, str
 	Function_t* func = newInsn->getFunction();
 	inserted_instr[func].insert(newInsn);
         inserted_addr[func].insert(newInsn->getAddress());
-        return newInsn;
+		if (verbose_log)
+		{
+			cout << "P1_insertAssemblyBefore is adding: " << assembly << endl;
+		}
+		return newInsn;
 }
 
 
@@ -55,7 +63,11 @@ Instruction_t* P1_insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, stri
 	Function_t* func = newInsn->getFunction();
 	inserted_instr[func].insert(newInsn);
         inserted_addr[func].insert(newInsn->getAddress());
-        return newInsn;
+		if (verbose_log)
+		{
+			cout << "P1_insertAssemblyAfter is adding: " << assembly << endl;
+		}
+		return newInsn;
 }
 
 
@@ -65,7 +77,11 @@ Instruction_t* P1_insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, stri
 	Function_t* func = newInsn->getFunction();
 	inserted_instr[func].insert(newInsn);
         inserted_addr[func].insert(newInsn->getAddress());
-        return newInsn;
+		if (verbose_log)
+		{
+			cout << "P1_insertAssemblyAfter is adding: " << assembly << endl;
+		}
+		return newInsn;
 }
 
 
diff --git a/PNMain.cpp b/PNMain.cpp
index 33476c07df27f20dede319bb321ee60168669502..575de9f812580a0761aaee565dee298c5b7bf21a 100644
--- a/PNMain.cpp
+++ b/PNMain.cpp
@@ -355,24 +355,33 @@ void parseYAMLNode(YAML::Node &currNode, PNOptions *currOptions)
 	}
 #endif
 
-#if 0	// canary types of float, top, and bottom do not seem to exist yet
 	YAML::Node canarytypenode = currNode["canary_type"];
 	if (!canarytypenode.IsNull() && canarytypenode.IsDefined())
 	{
 		string canarytypevalstr = canarytypenode.as<std::string>();
-		if (0 != canarytypevalstr.compare(""))
+		if (verbose_log)
 		{
-			// A particular auto_initialize canary value is specified.
-			int new_autoinit_value = stoi(autoinitvalstr, nullptr, 10);
-			int old_autoinit_value = currOptions->getCanaryValue();
-			if (new_autoinit_value != old_autoinit_value)
-			{
-				cout << "YAML: Changing auto_init canary value from " << old_autoinit_value << " to " << new_autoinit_value << endl;
-				currOptions->setCanaryValue(new_autoinit_value);
-			}
+			cout << "Found canary_type: " << canarytypevalstr << endl;
+		}
+		if (0 == canarytypevalstr.compare("top"))
+		{
+			currOptions->setCanaryType(C_CANARY_TOP);
+		}
+		else if (0 == canarytypevalstr.compare("float"))
+		{
+			currOptions->setCanaryType(C_CANARY_FLOATING);
+		}
+		else if (0 == canarytypevalstr.compare("bottom"))
+		{
+			currOptions->setCanaryType(C_CANARY_BOTTOM);
+		}
+		else
+		{
+			cout << "ERROR: Invalid canary type: " << canarytypevalstr << endl;
+			cout << "Keeping default canary type " << endl;
 		}
 	}
-#endif
+
 	return;
 } // end of parseYAMLNode()
 
diff --git a/PNStackLayout.cpp b/PNStackLayout.cpp
index d276e769bdbec96ff236b194f147d813845a1cb5..122278269f550ec01b016892a735483eb5ee9ebc 100644
--- a/PNStackLayout.cpp
+++ b/PNStackLayout.cpp
@@ -393,7 +393,7 @@ void PNStackLayout::AddRandomPadding(bool isaligned)
 	if (verbose_log)
 	{
 		cerr << "Last object size=0x" << hex << last_pad << endl;
-		cerr << "altered_aloc_size=0x" << hex << altered_alloc_size << endl;
+		cerr << "altered_alloc_size=0x" << hex << altered_alloc_size << endl;
 		cerr << "total_padding=0x" << hex << total_padding << endl;
 	}
 	
@@ -412,7 +412,7 @@ void PNStackLayout::AddRandomPadding(bool isaligned)
 		cerr << "PNStackLayout: AddPadding(): " << ToString() << endl;
 		for (unsigned int i = 0; i < mem_objects.size(); ++i)
 		{
-			cerr << "\tOffset = " << mem_objects[i]->getOffset() << " Size = " << mem_objects[i]->getSize() <<
+			cerr << dec << "\tOffset = " << mem_objects[i]->getOffset() << " Size = " << mem_objects[i]->getSize() <<
 				" Padding = " << mem_objects[i]->GetPaddingSize() << " displ = " << mem_objects[i]->GetDisplacement() << endl;
 		}
 	}	  
diff --git a/PNTransformDriver.cpp b/PNTransformDriver.cpp
index 52976fba0618c85d8f0fe90ac99165b23e6d087f..7078adfe15019d309fe81d88398df71fb023681e 100644
--- a/PNTransformDriver.cpp
+++ b/PNTransformDriver.cpp
@@ -118,7 +118,7 @@ PNTransformDriver::PNTransformDriver(VariantID_t *pidp,string BED_script, pqxxDB
 	orig_virp = NULL;
 	this->BED_script = BED_script;
 	do_canaries = true;
-	do_floating_canary = false;
+	this->do_floating_canary = false;
 	do_align = false;
 	no_validation_level = -1;
 	coverage_threshold = -1;
@@ -2244,6 +2244,7 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f
 	//TODO: hack for TNE, assuming all virp is orig_virp now. 
 	FileIR_t *virp = orig_virp;
 
+	// TODO: Should we getFuncOptions inside Sans_Canary_Rewrite() to allow overrides there?
 	if (!orig_layout->IsCanarySafe())
 		return Sans_Canary_Rewrite(orig_layout,func);
 
@@ -2253,28 +2254,45 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f
 
 	vector<PNRange*> mem_objects = layout->GetRanges();
 
+	PNOptions *funcOptions = getFuncOptions((int32_t) func->getBaseID());
+
+	unsigned int paddingAdded = (layout->GetAlteredAllocSize() - layout->GetOriginalAllocSize());
+	bool floatingCanaryFlag = (funcOptions->getCanaryType() == C_CANARY_FLOATING);
+	bool topCanaryFlag = (funcOptions->getCanaryType() == C_CANARY_TOP);
+	if (verbose_log)
+	{
+		cout << "Padding added: " << paddingAdded << " topCanaryFlag: " << topCanaryFlag << endl;
+	}
+
 	for (unsigned int i = 0; i < mem_objects.size(); ++i)
 	{
 		canary c;
 
 		int floating_canary_offset = 0;
 
-		if (do_floating_canary)
+		int reg_size = get_saved_reg_size();
+
+		if (floatingCanaryFlag)
 		{
 			// nb: get_saved_reg_size is 4 or 8 depending on architecture
-			int reg_size = get_saved_reg_size();
-			floating_canary_offset = (rand() % (layout->GetAlteredAllocSize() - layout->GetOriginalAllocSize() - reg_size));
+			floating_canary_offset = (rand() % (paddingAdded - reg_size));
 			floating_canary_offset -= (floating_canary_offset % reg_size);
 			assert(floating_canary_offset >= 0);
-			c.floating_offset = floating_canary_offset;
-		}
-		else 
-		{
-			c.floating_offset = 0;
 		}
+		c.floating_offset = floating_canary_offset;
 
+		// This code assumes a bottom-of-the-padding canary or a floating (middle of padding) canary.
 		c.esp_offset = mem_objects[i]->getOffset() + mem_objects[i]->GetDisplacement() + mem_objects[i]->getSize();
 		c.esp_offset += floating_canary_offset;
+		if (topCanaryFlag && (0 < paddingAdded))
+		{
+			if (verbose_log)
+			{
+				cout << "Canary_Rewrite is using a top canary_type " << endl;
+			}
+			assert(paddingAdded >= reg_size);
+			c.esp_offset += (paddingAdded - reg_size);
+		}
 
 		assert(c.esp_offset >= 0);
 
diff --git a/globals.h b/globals.h
index 371dc88339f9cf9ba1edc61730e5fc16de05086a..62101cbb7468e212c41bc4001c09e66fd12209d9 100644
--- a/globals.h
+++ b/globals.h
@@ -47,7 +47,11 @@ enum mitigation_policy
 	P_HARD_EXIT
 };
 
-
+enum canaryTypeEnum {
+	C_CANARY_TOP,
+	C_CANARY_BOTTOM,
+	C_CANARY_FLOATING
+};
 
 class PNOptions 
 {
@@ -70,6 +74,7 @@ class PNOptions
 			spri_validate=false;
 			detection_policy=P_HARD_EXIT;
 			detection_exit_code=DEFAULT_DETECTION_EXIT_CODE;
+			canary_type = C_CANARY_BOTTOM;
 		}
 
 		void setMinStackPadding(int val) { min_stack_padding = val; }
@@ -120,6 +125,8 @@ class PNOptions
 		mitigation_policy getDetectionPolicy() const { return detection_policy; } 
 		unsigned getDetectionExitCode() const { return detection_exit_code; }
 		void setDetectionExitCode(unsigned p_exitCode) { detection_exit_code = p_exitCode; }
+		canaryTypeEnum getCanaryType(void) const { return canary_type; };
+		void setCanaryType(const canaryTypeEnum newType) { canary_type = newType; };
 
 	private:
 		int min_stack_padding;
@@ -140,6 +147,7 @@ class PNOptions
 		std::set<std::string> canary_functions;
 
 		mitigation_policy detection_policy;
+		canaryTypeEnum canary_type;
 		unsigned detection_exit_code;
 };
 
@@ -147,7 +155,7 @@ extern PNOptions *pn_options;
 
 // Get YAML override options for FuncAddress and insert them into a copy of
 //  the global PNOptions and return it. If no overrides, return global options.
-PNOptions *getFuncOptions(int32_t FuncID);
+extern PNOptions *getFuncOptions(int32_t FuncID);
 
 
 #endif