diff --git a/afl_transforms/tools/zax/zax.cpp b/afl_transforms/tools/zax/zax.cpp
index 351671a2d8a7437007bddbdd220dc723f0c61369..f11e920d6727b4a88d9d7b04512c05e2363efd99 100644
--- a/afl_transforms/tools/zax/zax.cpp
+++ b/afl_transforms/tools/zax/zax.cpp
@@ -81,16 +81,22 @@ void Zax_t::instrumentBasicBlock(BasicBlock_t *p_bb, const bool p_honorRedZone,
 	auto save_context = (getContextSensitivity() != ContextSensitivity_None) ? true : false;
 	auto block_record=BBRecord_t();
 
-	const auto trace_map_fixed_addr       = getenv("ZAFL_TRACE_MAP_FIXED_ADDRESS");
-	const auto do_fixed_addr_optimization = (trace_map_fixed_addr!=nullptr);
+	// if fixed address, only need 1 register
+	// if not, need up to 4 registers
+	auto num_free_regs_desired = save_context ? 4 : 3;
+	if (useFixedAddresses())
+		num_free_regs_desired = 1; 
 
-	const auto num_free_regs_desired = save_context ? 4 : 3;
 	auto instr = getInstructionToInstrument(p_bb, num_free_regs_desired);
 	if (!instr) throw;
 
 	// don't try to reserve the trace_map reg if we aren't using it.
-	if(do_fixed_addr_optimization)  
+	if(useFixedAddresses())  
+	{
 		save_trace_map=false;
+		save_prev_id=false;
+		save_context=false;
+	}
 
 	block_record.push_back(instr);
 
@@ -118,7 +124,7 @@ void Zax_t::instrumentBasicBlock(BasicBlock_t *p_bb, const bool p_honorRedZone,
 				save_trace_map = false;
 				free_regs.erase(r);
 			}
-			else if (r == rn_RDX)
+			else if (r == rn_RDX && save_prev_id)
 			{
 				reg_prev_id = strdup("rdx");
 				save_prev_id = false;
@@ -164,7 +170,7 @@ void Zax_t::instrumentBasicBlock(BasicBlock_t *p_bb, const bool p_honorRedZone,
 
 		if (getContextSensitivity() != ContextSensitivity_None)
 		{
-			if (free_regs.size() >= 1)
+			if (save_context && free_regs.size() >= 1)
 			{
 				auto r = *free_regs.begin();
 				auto r16 = convertRegisterTo16bit(r);
@@ -262,23 +268,29 @@ void Zax_t::instrumentBasicBlock(BasicBlock_t *p_bb, const bool p_honorRedZone,
 	// load the previous block ID.
 	//   0:   mov    rdx,QWORD PTR [rip+0x0]        # 7 <f+0x7>
 // FIXME:  Why are we doing this if we aren't bothering to hash the previous block ID?
-	sprintf(buf, "P%d: mov  %s, QWORD [rel P%d]", labelid, reg_prev_id, labelid); // rdx
-	do_insert(buf);
-	create_got_reloc(getFileIR(), m_prev_id, tmp);
 
-	
-	if (getContextSensitivity() != ContextSensitivity_None)
+	if (!useFixedAddresses())
 	{
-		sprintf(buf, "C%d: mov  %s, QWORD [rel C%d]", labelid, reg_context, labelid); 
+		sprintf(buf, "P%d: mov  %s, QWORD [rel P%d]", labelid, reg_prev_id, labelid); // rdx
 		do_insert(buf);
-		create_got_reloc(getFileIR(), m_context_id, tmp);
+		create_got_reloc(getFileIR(), m_prev_id, tmp);
+	}
 
-		sprintf(buf,"mov %s, [%s]", reg_context, reg_context);
-		do_insert(buf);
+	if (getContextSensitivity() != ContextSensitivity_None)
+	{
+		if (!useFixedAddresses())
+		{
+			sprintf(buf, "C%d: mov  %s, QWORD [rel C%d]", labelid, reg_context, labelid); 
+			do_insert(buf);
+			create_got_reloc(getFileIR(), m_context_id, tmp);
+
+			sprintf(buf,"mov %s, [%s]", reg_context, reg_context);
+			do_insert(buf);
+		}
 	}
 
 	// if we are using a variable address trace map, generate the address.
-	if(!do_fixed_addr_optimization)
+	if(!useFixedAddresses())
 	{
 		//   7:   mov    rcx,QWORD PTR [rip+0x0]        # e <f+0xe>
 		sprintf(buf, "T%d: mov  %s, QWORD [rel T%d]", labelid, reg_trace_map, labelid); 
@@ -292,7 +304,14 @@ void Zax_t::instrumentBasicBlock(BasicBlock_t *p_bb, const bool p_honorRedZone,
 	if (!p_collafl_optimization)
 	{
 		//   e:   movzx  eax,WORD PTR [rdx]                      
-		sprintf(buf,"movzx  %s,WORD [%s]", reg_temp32, reg_prev_id);
+		if (useFixedAddresses())
+		{
+			sprintf(buf,"movzx  %s,WORD [0x%lx]", reg_temp32, getFixedAddressPrevId());
+		}
+		else
+		{
+			sprintf(buf,"movzx  %s,WORD [%s]", reg_temp32, reg_prev_id);
+		}
 		do_insert(buf);
 
 		//  11:   xor    ax,0x1234                              
@@ -302,9 +321,17 @@ void Zax_t::instrumentBasicBlock(BasicBlock_t *p_bb, const bool p_honorRedZone,
 		// hash with calling context value
 		if (getContextSensitivity() != ContextSensitivity_None)
 		{
-			// xor ax, <context_id_register>
-			sprintf(buf, "xor   %s,%s", reg_temp16, reg_context16);
-			do_insert(buf);
+			if (useFixedAddresses())
+			{
+				sprintf(buf, "xor   %s,WORD [0x%lx]", reg_temp16, getFixedAddressContext());
+				do_insert(buf);
+			}
+			else
+			{
+				// xor ax, <context_id_register>
+				sprintf(buf, "xor   %s,%s", reg_temp16, reg_context16);
+				do_insert(buf);
+			}
 		}
 
 		//  15:   movzx  eax,ax                                
@@ -320,11 +347,11 @@ void Zax_t::instrumentBasicBlock(BasicBlock_t *p_bb, const bool p_honorRedZone,
 	}
 
 	// write into the trace map.
-	if(do_fixed_addr_optimization)
+	if(useFixedAddresses())
 	{
 		// do it the fast way with the fixed-adresss trace map
 		//  1b:   80 00 01                add    BYTE PTR [rax],0x1                  
-		sprintf(buf,"add    BYTE [%s + 0x%lx],0x1", reg_temp, strtoul(trace_map_fixed_addr,nullptr,0) );
+		sprintf(buf,"add    BYTE [%s + 0x%lx],0x1", reg_temp, getFixedAddressMap());
 		do_insert(buf);
 	}
 	else
@@ -342,13 +369,21 @@ void Zax_t::instrumentBasicBlock(BasicBlock_t *p_bb, const bool p_honorRedZone,
 	// write out block id into zafl_prev_id for the next instrumentation.
 // FIXME:  Why are we doing this if we aren't bothering to hash the previous block ID?
 	//  1e:   mov    eax,0x91a                          
-	sprintf(buf, "mov   %s, 0x%x", reg_temp32, blockid >> 1);
-	do_insert(buf);
+	if (useFixedAddresses())
+	{
+		sprintf(buf, "mov   WORD [0x%lx], 0x%x", getFixedAddressPrevId(), blockid >> 1);
+		do_insert(buf);
+	}
+	else
+	{
+		sprintf(buf, "mov   %s, 0x%x", reg_temp32, blockid >> 1);
+		do_insert(buf);
 
-	// store prev_id
-	//  23:   mov    WORD PTR [rdx],ax       
-	sprintf(buf, "mov    WORD [%s], %s", reg_prev_id, reg_temp16);
-	do_insert(buf);
+		// store prev_id
+		//  23:   mov    WORD PTR [rdx],ax       
+		sprintf(buf, "mov   WORD [%s], %s", reg_prev_id, reg_temp16);
+		do_insert(buf);
+	}
 
 	// finally, restore any flags/registers so that the program can execute.
 	if (live_flags)       do_insert("popf");
diff --git a/afl_transforms/tools/zax/zax_base.cpp b/afl_transforms/tools/zax/zax_base.cpp
index 80eb4f00cfee3d22cfb2ba6c8083339bfe1da44b..f0bf3bf975509152dad9af764a424ccdeac9c5ca 100644
--- a/afl_transforms/tools/zax/zax_base.cpp
+++ b/afl_transforms/tools/zax/zax_base.cpp
@@ -179,6 +179,48 @@ ZaxBase_t::ZaxBase_t(IRDB_SDK::pqxxDB_t &p_dbinterface, IRDB_SDK::FileIR_t *p_va
 	m_num_entry_blocks_elided = 0;
 	m_num_single_block_function_elided = 0;
 	m_num_contexts = 0;
+
+	// fixed addresses (must match libzafl)
+	const auto trace_map_fixed_addr_s = getenv("ZAFL_TRACE_MAP_FIXED_ADDRESS");
+	m_do_fixed_addr_optimization = (trace_map_fixed_addr_s!=nullptr);
+
+	if (m_do_fixed_addr_optimization) {
+		cout << "fixed address optimization enabled" << endl;
+		m_trace_map_fixed_addr = strtoul(trace_map_fixed_addr_s,nullptr,0);
+		m_previd_fixed_addr = m_trace_map_fixed_addr + 65536 + 4096 + 32;
+		m_context_fixed_addr = m_trace_map_fixed_addr + 65536 + 4096 + 64;
+		cout << hex;
+		cout << "tracemap fixed at: 0x" << m_trace_map_fixed_addr << endl;
+		cout << "prev_id fixed at : 0x" << m_previd_fixed_addr << endl;
+		cout << "context fixed at : 0x" << m_context_fixed_addr << endl;
+		cout << dec;
+	}
+	else
+	{
+		m_trace_map_fixed_addr = 0;
+		m_previd_fixed_addr = 0;
+		m_context_fixed_addr = 0;
+	}
+}
+
+bool ZaxBase_t::useFixedAddresses() const
+{
+	return m_do_fixed_addr_optimization;
+}
+
+unsigned long ZaxBase_t::getFixedAddressMap() const
+{
+	return m_trace_map_fixed_addr;
+}
+
+unsigned long ZaxBase_t::getFixedAddressPrevId() const
+{
+	return m_previd_fixed_addr;
+}
+
+unsigned long ZaxBase_t::getFixedAddressContext() const
+{
+	return m_context_fixed_addr;
 }
 
 void ZaxBase_t::setVerbose(bool p_verbose)
@@ -941,19 +983,38 @@ void ZaxBase_t::addContextSensitivity_Function(const ControlFlowGraph_t& cfg)
 	auto compute_hash_chain = [&](ZaflContextId_t contextid, Instruction_t * instr, string reg_context, string reg_temp) -> Instruction_t*
 		{
 			auto labelid = getLabelId();
-			const auto hash_context_reloc = string("E") + to_string(labelid) + ": mov " + reg_context + ", QWORD [rel E" + to_string(labelid) + "]"; 
 			auto tmp = instr;
-			tmp = do_insert(tmp, hash_context_reloc);
-			create_got_reloc(getFileIR(), m_context_id, tmp);
+
+			// fast way with fixed addresses:
+			//         xor [regc], <context_id>
+			//
+			// inefficient way:
+			//      E: mov   regc, QWORD[rel E]
+			//         mov   rtmp, [regc]
+			//         xor   rtmp, <context_id>
+			//         mov [regc], rtmp
+			//
+			//         
+			if (useFixedAddresses())
+			{
+				const auto xor_context = string("xor WORD [0x") + to_hex_string(getFixedAddressContext()) + "]" + "," + to_string(contextid);
+				tmp = do_insert(tmp, xor_context);
+			}
+			else
+			{
+				const auto hash_context_reloc = string("E") + to_string(labelid) + ": mov " + reg_context + ", QWORD [rel E" + to_string(labelid) + "]"; 
+				tmp = do_insert(tmp, hash_context_reloc);
+				create_got_reloc(getFileIR(), m_context_id, tmp);
 			
-			const auto deref_context = string("mov ") + reg_temp + ", [" + reg_context + "]";
-			tmp = do_insert(tmp, deref_context);
+				const auto deref_context = string("mov ") + reg_temp + ", [" + reg_context + "]";
+				tmp = do_insert(tmp, deref_context);
 
-			const auto hash_chain = string("xor ") + reg_temp + ", " + to_string(contextid);
-			tmp = do_insert(tmp, hash_chain);
+				const auto hash_chain = string("xor ") + reg_temp + ", " + to_string(contextid);
+				tmp = do_insert(tmp, hash_chain);
 
-			const auto store_context = string("mov [") + reg_context + "]" + "," + reg_temp;
-			tmp = do_insert(tmp, store_context);
+				const auto store_context = string("mov [") + reg_context + "]" + "," + reg_temp;
+				tmp = do_insert(tmp, store_context);
+			}
 
 			return tmp;
 		};
@@ -965,8 +1026,14 @@ void ZaxBase_t::addContextSensitivity_Function(const ControlFlowGraph_t& cfg)
 			// look for instruction in entry block with at least 1 free reg
 			auto reg_context = string("r14");
 			auto reg_temp = string("r15");
-			bool save_context = false;
-			bool save_temp = false;
+			bool save_context = true;
+			bool save_temp = true;
+
+			if (useFixedAddresses())
+			{
+				save_context = false;
+				save_temp = false;
+			}
 
 			const auto allowed_regs = RegisterSet_t({rn_RAX, rn_RBX, rn_RCX, rn_RDX, rn_R8, rn_R9, rn_R10, rn_R11, rn_R12, rn_R13, rn_R14, rn_R15});
 			const auto dead_regs = getDeadRegs(i);
@@ -976,27 +1043,25 @@ void ZaxBase_t::addContextSensitivity_Function(const ControlFlowGraph_t& cfg)
 			if (honor_red_zone)
 				i = do_insert(i, "lea rsp, [rsp-128]");
 
-			if (free_regs.size() > 0)
+			if (save_context && free_regs.size() > 0)
 			{
 				reg_context = registerToString(FIRSTOF(free_regs));
 				free_regs.erase(FIRSTOF(free_regs));
-			}
-			else
-			{
-				save_context = true;
-				i = do_insert(i, "push " + reg_context);
+				save_context = false;
 			}
 
-			if (free_regs.size() > 0)
+			if (save_temp && free_regs.size() > 0)
 			{
 				reg_temp = registerToString(FIRSTOF(free_regs));
 				free_regs.erase(FIRSTOF(free_regs));
+				save_temp = false;
 			}
-			else
-			{
-				save_temp = true;
+
+			if (save_context)
+				i = do_insert(i, "push " + reg_context);
+
+			if (save_temp)
 				i = do_insert(i, "push " + reg_temp);
-			}
 
 			if (live_flags)
 				i = do_insert(i, "pushf");
diff --git a/afl_transforms/tools/zax/zax_base.hpp b/afl_transforms/tools/zax/zax_base.hpp
index 0083cef2e0f8dc69e3d8b60dbc2be8bacc365f62..772fc82a025d543cbcf8ffb84191602215a1224a 100644
--- a/afl_transforms/tools/zax/zax_base.hpp
+++ b/afl_transforms/tools/zax/zax_base.hpp
@@ -85,6 +85,11 @@ namespace Zafl
 			void addContextSensitivity_Callsite(const ControlFlowGraph_t&);
 			void addContextSensitivity_Function(const ControlFlowGraph_t&);
 
+			bool useFixedAddresses() const;
+			unsigned long getFixedAddressMap() const;
+			unsigned long getFixedAddressPrevId() const;
+			unsigned long getFixedAddressContext() const;
+
 		protected:
 			pqxxDB_t&                      m_dbinterface;
 			unique_ptr<FunctionSet_t>      leaf_functions;
@@ -108,6 +113,8 @@ namespace Zafl
 
 			ContextSensitivity_t           m_context_sensitivity;  // none, @callsite, @function
 
+
+
 			// stats
 			size_t m_num_bb;
 			size_t m_num_bb_instrumented;
@@ -133,6 +140,12 @@ namespace Zafl
 			ZaflBlockId_t   m_blockid;            // internal bookkeeping to generate labels
 			Instruction_t*  m_entry_point;        // entry point where fork server was inserted
 
+			// fixed address mode
+			bool            m_do_fixed_addr_optimization;
+			unsigned long   m_trace_map_fixed_addr;
+			unsigned long   m_previd_fixed_addr;
+			unsigned long   m_context_fixed_addr;
+
 	};
 } 
 
diff --git a/bin/zafl.sh b/bin/zafl.sh
index 8af80beecec7773afe94257545943eb0952b9d10..5d863327043e18d82b241bb588e7a76a17b11359 100755
--- a/bin/zafl.sh
+++ b/bin/zafl.sh
@@ -36,7 +36,9 @@ usage()
 	echo "     -M, --disable-fixed-map                 Disable fixed address tracing map (default)"
 	echo "     -i, --enable-floating-instrumentation   Select best instrumentation point within basic block (default)"
 	echo "     -I, --disable-floating-instrumentation  Use first instruction for instrumentation in basic blocks"
-	echo "     --enable-context-sensitivity <style>      style={callsite,function} only function supported currently"
+	echo "     --enable-context-sensitivity <style>    style={callsite,function} only function supported currently"
+#	echo "     -l, --enable-locality                   Maintain code locality (best effort) when instrumenting binary"
+#	echo "     -L, --disable-locality                  Randomized layout when instrumenting binary"
 	echo "     -v                                      Verbose mode" 
 	echo 
 }
@@ -47,6 +49,8 @@ zax_opt=""
 other_args=""
 float_opt=" -o zax:--enable-floating-instrumentation "
 context_sensitivity_opt=""
+trace_opt=""
+
 
 me=$(whoami)
 tmp_dir=/tmp/${me}/$$
@@ -207,7 +211,14 @@ parse_args()
 					;;
 				esac
 				;;
-
+			-l | --enable-locality)
+				trace_opt=" --step-option zipr:--traceplacement:on --step-option zipr:true "
+				shift
+				;;
+			-L | --disable-locality)
+				trace_opt=""
+				shift
+				;;
 			-*|--*=) # unsupported flags
 				echo "Error: Unsupported flag $1" >&2
 				exit 1
@@ -249,7 +260,7 @@ find_main()
 
 	if [  $? -eq 0 ]; then
 		main_addr=$(cut -d' ' -f1 $tmp_main)
-		log_msg "detected main at: 0x$main_addr"
+		log_msg "Detected main at: 0x$main_addr"
 		options=" $options -o zax:'-e 0x$main_addr'"
 	else
 		grep -B1 "libc_start_main@" $tmp_objdump >/dev/null 2>&1
@@ -314,7 +325,7 @@ fi
 log_msg "Transforming input binary $input_binary into $output_zafl_binary"
 
 zax_opt=" $zax_opt $float_opt $context_sensitivity_opt "
-cmd="$ZAFL_TM_ENV $PSZ $input_binary $output_zafl_binary $ida_or_rida_opt -c move_globals=on -c zax=on -o move_globals:--elftables-only $stars_opt $zax_opt $verbose_opt $options $other_args"
+cmd="$ZAFL_TM_ENV $PSZ $input_binary $output_zafl_binary $ida_or_rida_opt -c move_globals=on -c zax=on -o move_globals:--elftables-only $stars_opt $zax_opt $verbose_opt $options $other_args $trace_opt"
 
 if [ ! -z "$ZAFL_TM_ENV" ]; then
 	log_msg "Trace map will be expected at fixed address"
@@ -322,6 +333,10 @@ if [ ! -z "$ZAFL_TM_ENV" ]; then
 		log_warning "When running afl-fuzz, make sure that the environment variable ZAFL_TRACE_MAP_FIXED_ADDRESS is exported and set properly to (otherwise the instrumented binary will crash):"
 		log_warning "export $ZAFL_TM_ENV"
 	fi
+else
+	if [ ! -z $ZAFL_TRACE_MAP_FIXED_ADDRESS ]; then
+		log_msg "Trace map will be at fixed address: $ZAFL_TRACE_MAP_FIXED_ADDRESS"
+	fi
 fi
 
 log_msg "Issuing command: $cmd"
diff --git a/libzafl b/libzafl
index 97b561cb943dd9a15b3388cb19bd457eaf98fa37..5bcb4a8dbae1af977384ceda3b92e402f3c7f67d 160000
--- a/libzafl
+++ b/libzafl
@@ -1 +1 @@
-Subproject commit 97b561cb943dd9a15b3388cb19bd457eaf98fa37
+Subproject commit 5bcb4a8dbae1af977384ceda3b92e402f3c7f67d