diff -crB libdft-ng_linux-i386.orig/src/libdft_api.c libdft-ng_linux-i386.patched/src/libdft_api.c
*** libdft-ng_linux-i386.orig/src/libdft_api.c	2013-03-15 20:20:09.000000000 +0100
--- libdft-ng_linux-i386.patched/src/libdft_api.c	2018-08-16 14:41:39.503960715 +0200
***************
*** 40,45 ****
--- 40,46 ----
  #include <errno.h>
  #include <string.h>
  #include <unistd.h>
+ #include <assert.h>
  
  #include "libdft_api.h"
  #include "libdft_core.h"
***************
*** 645,663 ****
  /* static inline */ size_t
  REG32_INDX(REG reg)
  {
- 	/* result; for the 32-bit registers the mapping is easy */
- 	size_t indx = reg - R32_ALIGN;
- 	
  	/* 
! 	 * sanity check;
! 	 * unknown registers are mapped to the scratch
! 	 * register of the VCPU
  	 */
! 	if (unlikely(indx > GRP_NUM))
! 		indx = GRP_NUM;
! 	
! 	/* return the index */
! 	return indx;	
  }
  
  /* 
--- 646,706 ----
  /* static inline */ size_t
  REG32_INDX(REG reg)
  {
  	/* 
! 	 * differentiate based on the register;
! 	 * see mapping in struct vcpu_ctx_t in libdft_api.h
  	 */
! 	switch (reg) {
! 		/* di */
! 		case LEVEL_BASE::REG::REG_EDI:
! 			return 0;
! 			/* not reached; safety */
! 			break;
! 		/* si */
! 		case LEVEL_BASE::REG::REG_ESI:
! 			return 1;
! 			/* not reached; safety */
! 			break;
! 		/* bp */
! 		case LEVEL_BASE::REG::REG_EBP:
! 			return 2;
! 			/* not reached; safety */
! 			break;
! 		/* sp */
! 		case LEVEL_BASE::REG::REG_ESP:
! 			return 3;
! 			/* not reached; safety */
! 			break;
! 		/* bx */
! 		case LEVEL_BASE::REG::REG_EBX:
! 			return 4;
! 			/* not reached; safety */
! 			break;
! 		/* dx */
! 		case LEVEL_BASE::REG::REG_EDX:
! 			return 5;
! 			/* not reached; safety */
! 			break;
! 		/* cx */
! 		case LEVEL_BASE::REG::REG_ECX:
! 			return 6;
! 			/* not reached; safety */
! 			break;
! 		/* ax */
! 		case LEVEL_BASE::REG::REG_EAX:
! 			return 7;
! 			/* not reached; safety */
! 			break;
! 		default:
! 			/* 
! 			 * paranoia;
! 			 * unknown 32-bit registers are mapped
! 			 * to the scratch register of the VCPU
! 			 */
! 			//return 8;
! 			assert(reg < LEVEL_BASE::REG::REG_LAST);
! 			return GRP_NUM + reg;
! 	}
  }
  
  /* 
***************
*** 723,729 ****
  			 * unknown 16-bit registers are mapped
  			 * to the scratch register of the VCPU
  			 */
! 			return 8;
  	}
  }
  
--- 766,774 ----
  			 * unknown 16-bit registers are mapped
  			 * to the scratch register of the VCPU
  			 */
! 			//return 8;
! 			assert(reg < LEVEL_BASE::REG::REG_LAST);
! 			return GRP_NUM + reg;
  	}
  }
  
***************
*** 774,779 ****
  			 * unknown 8-bit registers are mapped
  			 * to the scratch register
  			 */
! 			return 8;
  	}
  }
--- 819,826 ----
  			 * unknown 8-bit registers are mapped
  			 * to the scratch register
  			 */
! 			//return 8;
! 			assert(reg < LEVEL_BASE::REG::REG_LAST);
! 			return GRP_NUM + reg;
  	}
  }
diff -crB libdft-ng_linux-i386.orig/src/libdft_api.h libdft-ng_linux-i386.patched/src/libdft_api.h
*** libdft-ng_linux-i386.orig/src/libdft_api.h	2013-03-15 20:20:09.000000000 +0100
--- libdft-ng_linux-i386.patched/src/libdft_api.h	2018-08-16 14:41:39.611961206 +0200
***************
*** 106,112 ****
  	 * 	7: EAX
  	 * 	8: scratch (not a real register; helper) 
  	 */
! 	uint32_t gpr[GRP_NUM + 1];
  } vcpu_ctx_t;
  
  /*
--- 106,113 ----
  	 * 	7: EAX
  	 * 	8: scratch (not a real register; helper) 
  	 */
! 	//uint32_t gpr[GRP_NUM + 1];
! 	uint32_t gpr[LEVEL_BASE::REG::REG_LAST + GRP_NUM + 1];
  } vcpu_ctx_t;
  
  /*
diff -crB libdft-ng_linux-i386.orig/src/libdft_core.c libdft-ng_linux-i386.patched/src/libdft_core.c
*** libdft-ng_linux-i386.orig/src/libdft_core.c	2013-03-15 20:20:09.000000000 +0100
--- libdft-ng_linux-i386.patched/src/libdft_core.c	2018-08-16 14:41:39.179959236 +0200
***************
*** 2117,2122 ****
--- 2117,2136 ----
  	*(uint32_t *)(dst_val + 28) = thread_ctx->vcpu.gpr[7];
  }
  
+ #ifdef DEBUG_MEMOPS
+ static void PIN_FAST_ANALYSIS_CALL
+ log_memory_read(ADDRINT ip, ADDRINT addr)
+ {
+ 	fprintf(stderr, "0x%x: R 0x%x\n", ip, addr);
+ }
+ 
+ static void PIN_FAST_ANALYSIS_CALL
+ log_memory_write(ADDRINT ip, ADDRINT addr)
+ {
+ 	fprintf(stderr, "0x%x: W 0x%x\n", ip, addr);
+ }
+ #endif
+ 
  /*
   * instruction inspection (instrumentation function)
   *
***************
*** 2147,2152 ****
--- 2161,2183 ----
  		return;
  	}
  
+ #ifdef DEBUG_MEMOPS
+ 	(void)fprintf(stderr, "0x%x: %s\n", INS_Address(ins), INS_Disassemble(ins).c_str());
+ 	if(INS_IsMemoryRead(ins) || INS_IsMemoryWrite(ins)) {
+ 		for(uint32_t memOp = 0; memOp < INS_MemoryOperandCount(ins); memOp++) {
+ 			if(INS_MemoryOperandIsRead(ins, memOp)) {
+ 				INS_InsertPredicatedCall(
+ 					ins, IPOINT_BEFORE, (AFUNPTR)log_memory_read,
+ 					IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_END);
+ 			} else if(INS_MemoryOperandIsWritten(ins, memOp)) {
+ 				INS_InsertPredicatedCall(
+ 					ins, IPOINT_BEFORE, (AFUNPTR)log_memory_write,
+ 					IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_END);
+ 			}
+ 		}
+ 	}
+ #endif
+ 
  	/* analyze the instruction */
  	switch (ins_indx) {
  		/* adc */
diff -crB libdft-ng_linux-i386.orig/src/Makefile libdft-ng_linux-i386.patched/src/Makefile
*** libdft-ng_linux-i386.orig/src/Makefile	2013-03-15 20:20:09.000000000 +0100
--- libdft-ng_linux-i386.patched/src/Makefile	2018-08-16 14:41:39.659961425 +0200
***************
*** 30,36 ****
  
  # get system information
  OS=$(shell uname -o | grep Linux$$)			# OS
! ARCH=$(shell uname -m | grep 86$$)			# arch
  KVER=$(subst -, ,$(subst ., ,$(shell uname -r)))	# kernel version (temp)
  
  # kernel version in compact format (e.g., 2.6.26-2-686-bigmem is 2626)
--- 30,37 ----
  
  # get system information
  OS=$(shell uname -o | grep Linux$$)			# OS
! #ARCH=$(shell uname -m | grep 86$$)			# arch
! ARCH=$(shell uname -m | grep "x86_64\|86$$")
  KVER=$(subst -, ,$(subst ., ,$(shell uname -r)))	# kernel version (temp)
  
  # kernel version in compact format (e.g., 2.6.26-2-686-bigmem is 2626)
***************
*** 51,59 ****
  endif
  # check the architecture (must be x86, i386, i486, i686, ...)
  ifeq ($(strip $(ARCH)),)
! 	$(error "This version of libdft is for x86 only")
  endif
  
  
  # libdft
  $(LIB): $(OBJS)
--- 52,64 ----
  endif
  # check the architecture (must be x86, i386, i486, i686, ...)
  ifeq ($(strip $(ARCH)),)
! 	$(error "This version of libdft is for x86 and x86_64 only")
  endif
  
+ # check need for cross-compile.
+ ifeq ($(findstring "x86_64", $(ARCH)),)
+ CXXFLAGS += -m32 
+ endif
  
  # libdft
  $(LIB): $(OBJS)
diff -crB libdft-ng_linux-i386.orig/src/syscall_desc.c libdft-ng_linux-i386.patched/src/syscall_desc.c
*** libdft-ng_linux-i386.orig/src/syscall_desc.c	2013-03-15 20:20:09.000000000 +0100
--- libdft-ng_linux-i386.patched/src/syscall_desc.c	2018-08-16 14:41:40.003962995 +0200
***************
*** 132,138 ****
  	/* __NR_unlink */
  	{ 1, 0, 0, { 0, 0, 0, 0, 0, 0 }, NULL, NULL },	/* 10 */
  	/* __NR_execve */
! 	{ 1, 0, 0, { 0, 0, 0, 0, 0, 0 }, NULL, NULL },
  	/* __NR_chdir */
  	{ 1, 0, 0, { 0, 0, 0, 0, 0, 0 }, NULL, NULL },
  	/* __NR_time */
--- 132,138 ----
  	/* __NR_unlink */
  	{ 1, 0, 0, { 0, 0, 0, 0, 0, 0 }, NULL, NULL },	/* 10 */
  	/* __NR_execve */
! 	{ 3, 1, 0, { 0, 0, 0, 0, 0, 0 }, NULL, NULL },  /* XXX: daa -- changed nargs from 1 to 3 and set save_args to 1 */
  	/* __NR_chdir */
  	{ 1, 0, 0, { 0, 0, 0, 0, 0, 0 }, NULL, NULL },
  	/* __NR_time */
diff -crB libdft-ng_linux-i386.orig/src/tagmap.c libdft-ng_linux-i386.patched/src/tagmap.c
*** libdft-ng_linux-i386.orig/src/tagmap.c	2013-03-15 20:20:09.000000000 +0100
--- libdft-ng_linux-i386.patched/src/tagmap.c	2018-08-16 14:41:39.979962886 +0200
***************
*** 83,93 ****
  
  /* ``hardcoded'' tagmap segments */
  void		*null_seg	= NULL;
- #ifdef TAGMAP_COLLAPSE
  void		*zero_seg	= NULL;
- #else
- static void	*zero_seg	= NULL;
- #endif
  
  /*
   * track when the dynamic linker/loader
--- 83,89 ----
***************
*** 97,102 ****
--- 93,133 ----
  static
  size_t dynldlnk_loaded	= 0;
  
+ static void
+ stackrange_alloc(uint32_t addrstart, uint32_t addrend)
+ {
+ 	size_t	i, j;	/* iterators		*/
+ 	size_t size = addrend - addrstart;
+ 
+ 	void	*stack_seg	= NULL;
+ 	/* stack_seg; zero_seg, null_seg; default segments */
+ 	if((stack_seg = mmap(NULL, size, /* RW- */
+ 		PROT_READ | PROT_WRITE, MAP_FLAGS, -1, 0)) == MAP_FAILED) {
+ 		perror("mmap");
+ 		exit(1);
+ 	}
+ 
+ 	/* 
+ 	 * stack mapping
+ 	 */
+ 	for (i = VIRT2STAB(addrstart), j = 0;
+ 			i <= VIRT2STAB(addrend-1); i++, j++) {
+ 		STAB[i] = (uint32_t)stack_seg - STAB2VIRT(i) + (j * PAGE_SZ);
+ 
+ #ifdef DEBUG_MEMTRACK
+ 		/* verbose */
+ 		LOG(string(__func__) + ": stack range " + hexstr(addrstart) + "-" + hexstr(addrend) + ": stack_seg\n");
+ #endif
+ 
+ 	}
+ 
+ #ifdef DEBUG_MEMTRACK
+ 	/* verbose */
+ 	LOG(string(__func__) + ": stack range " + hexstr(addrstart) + "-" + hexstr(addrend) + ": stack_seg\n");
+ #endif
+ 
+ }
+ 
  /*
   * get the starting and ending
   * addresses of the vDSO mapping
***************
*** 162,176 ****
  				break;
  			}
  		}
! 		
  		/* check for the vDSO entry */
  		if (strstr(lbuf, VDSO_STR) != NULL) {
  			/* update saddr and eaddr */
  			(void)sscanf(lbuf, "%x-%x %*s:4 %*x %*s:5 %*u%*s\n",
  					saddr, eaddr);
  			/* done */
! 			break;
  		}
  	}
  
  	/* cleanup */
--- 193,219 ----
  				break;
  			}
  		}
! 
! 		LOG(string(__func__) + ": map: " + lbuf);
! 
  		/* check for the vDSO entry */
  		if (strstr(lbuf, VDSO_STR) != NULL) {
  			/* update saddr and eaddr */
  			(void)sscanf(lbuf, "%x-%x %*s:4 %*x %*s:5 %*u%*s\n",
  					saddr, eaddr);
  			/* done */
! //			break;
! 		}
! 
! 		/* check for the stack entry */
! 		if (strstr(lbuf, "[stack:") != NULL || strstr(lbuf, " rw-") != NULL) {
! 			size_t s1, s2;
! 			/* update saddr and eaddr */
! 			(void)sscanf(lbuf, "%x-%x %*s:4 %*x %*s:5 %*u%*s\n",
! 					&s1, &s2);
! 			stackrange_alloc(s1, s2);
  		}
+ 
  	}
  
  	/* cleanup */
***************
*** 197,202 ****
--- 240,247 ----
  	void*	tseg;	/* tagmap segment		*/
  	size_t	slen;	/* segment length 		*/
  
+ 		LOG(string(__func__) + ": tagmap_collapse yes\n");
+ 
  	/* 
  	 * after the dynamic linker/loaded is mapped into
  	 * the address space of the process, the image loading
***************
*** 281,287 ****
  		 */
  		if (unlikely(((tseg = mmap(NULL, slen,
  			/* RW- */
! 			PROT_READ | PROT_WRITE | ~PROT_EXEC,
  			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED))) {
  			
  			/* error message */
--- 326,332 ----
  		 */
  		if (unlikely(((tseg = mmap(NULL, slen,
  			/* RW- */
! 			PROT_READ | PROT_WRITE,
  			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED))) {
  			
  			/* error message */
***************
*** 343,348 ****
--- 388,395 ----
  	void*	tseg;	/* tagmap segment		*/
  	size_t	slen;	/* segment length 		*/
  
+ 		LOG(string(__func__) + ": tagmap_collapse no\n");
+ 
  	/* 
  	 * after the dynamic linker/loaded is mapped into
  	 * the address space of the process, the image loading
***************
*** 354,361 ****
  
  #ifdef DEBUG_MEMTRACK
  	/* verbose */
! 	LOG(string(__func__) + ": " +
! 		IMG_Name(img) + " " +
  		hexstr(IMG_LowAddress(img)) + "-" +
  		hexstr(IMG_HighAddress(img)) + "\n");
  #endif
--- 401,408 ----
  
  #ifdef DEBUG_MEMTRACK
  	/* verbose */
! 	LOG(string(__func__) + ": image " +
! 		IMG_Name(img) + " low-high range: " +
  		hexstr(IMG_LowAddress(img)) + "-" +
  		hexstr(IMG_HighAddress(img)) + "\n");
  #endif
***************
*** 370,376 ****
  	 */
  	if (unlikely(((tseg = mmap(NULL, slen,
  		/* RW- */
! 		PROT_READ | PROT_WRITE | ~PROT_EXEC,
  		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED))) {
  			
  		/* error message */
--- 417,423 ----
  	 */
  	if (unlikely(((tseg = mmap(NULL, slen,
  		/* RW- */
! 		PROT_READ | PROT_WRITE,
  		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED))) {
  			
  		/* error message */
***************
*** 381,391 ****
  		/* die */
  		libdft_die();
  	}
  		
  	/* STAB setup */	
  	for (i = VIRT2STAB(IMG_LowAddress(img)), j = 0;
! 		i <= VIRT2STAB(IMG_HighAddress(img)); i++, j++)
  		STAB[i] = (uint32_t)tseg - STAB2VIRT(i) + (j * PAGE_SZ);
  #ifdef DEBUG_MEMTRACK
  		/* verbose */
  		LOG(string(__func__) + ": mapping sections " +
--- 428,443 ----
  		/* die */
  		libdft_die();
  	}
+ 
+ #ifdef DEBUG_MEMTRACK
+ 	LOG(string(__func__) + ": stab region for ELF image is " + hexstr(tseg) + "\n");
+ #endif
  		
  	/* STAB setup */	
  	for (i = VIRT2STAB(IMG_LowAddress(img)), j = 0;
! 		i <= VIRT2STAB(IMG_HighAddress(img)); i++, j++) {
  		STAB[i] = (uint32_t)tseg - STAB2VIRT(i) + (j * PAGE_SZ);
+         }
  #ifdef DEBUG_MEMTRACK
  		/* verbose */
  		LOG(string(__func__) + ": mapping sections " +
***************
*** 419,442 ****
   * initialize the STAB/tagmap
   *
   * allocate space for the STAB structure and the three ``hardcoded''
!  * tagmap segments: zero_seg (PAGE_SZ), null_seg (PAGE_SZ), and
!  * stack_seg (STACK_SZ)
   *
   * returns:	0 on success, 1 on error 
   */
  int
  tagmap_alloc(void)
  {
! 	size_t	i, j;	/* iterators		*/
  			/* STAB size in bytes	*/
  	size_t 	len		= STAB_SIZE * sizeof(uint32_t);
  			/* vDSO handling */
  	size_t	vdso_start, vdso_end;
  			/* stack segment */
! 	void	*stack_seg	= NULL;
! 		
  	/*
! 	 * allocate space for STAB/zero_seg/null_seg/stack_seg by invoking
  	 * mmap(2); if HUGE_TLB is defined, then the mapping is done using
  	 * ``huge pages''
  	 */
--- 472,494 ----
   * initialize the STAB/tagmap
   *
   * allocate space for the STAB structure and the three ``hardcoded''
!  * tagmap segments: zero_seg (PAGE_SZ), null_seg (PAGE_SZ)
   *
   * returns:	0 on success, 1 on error 
   */
  int
  tagmap_alloc(void)
  {
! 	size_t	i;	/* iterators		*/
  			/* STAB size in bytes	*/
  	size_t 	len		= STAB_SIZE * sizeof(uint32_t);
  			/* vDSO handling */
  	size_t	vdso_start, vdso_end;
  			/* stack segment */
! 
! 
  	/*
! 	 * allocate space for STAB/zero_seg/null_seg by invoking
  	 * mmap(2); if HUGE_TLB is defined, then the mapping is done using
  	 * ``huge pages''
  	 */
***************
*** 444,459 ****
  		/* STAB */
  		((STAB = (uint32_t *)mmap(NULL, len,
  			/* RW- */
! 			PROT_READ | PROT_WRITE | ~PROT_EXEC,
! 			MAP_FLAGS, -1, 0)) == MAP_FAILED)		||
! 		/* stack_seg; zero_seg, null_seg; default segments */
! 		((stack_seg = mmap(NULL, STACK_SZ,
! 			/* RW- */
! 			PROT_READ | PROT_WRITE | ~PROT_EXEC,
  			MAP_FLAGS, -1, 0)) == MAP_FAILED)		||
  		((zero_seg = mmap(NULL, PAGE_SZ,
  			/* R-- */
! 			PROT_READ | ~PROT_WRITE | ~PROT_EXEC,
  		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED)	||
  		((null_seg = mmap(NULL, PAGE_SZ,
  			/* --- */
--- 496,506 ----
  		/* STAB */
  		((STAB = (uint32_t *)mmap(NULL, len,
  			/* RW- */
! 			PROT_READ | PROT_WRITE,
  			MAP_FLAGS, -1, 0)) == MAP_FAILED)		||
  		((zero_seg = mmap(NULL, PAGE_SZ,
  			/* R-- */
! 			PROT_READ,
  		MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED)	||
  		((null_seg = mmap(NULL, PAGE_SZ,
  			/* --- */
***************
*** 467,472 ****
--- 514,521 ----
  		/* failed */
  		goto err;
  	}
+ 
+ 		LOG(string(__func__) + ": zero_seg ok\n");
  	
  	/* setup the STAB */
  
***************
*** 478,498 ****
  	for (i = VIRT2STAB(KERN_START); i <= VIRT2STAB(KERN_END); i++)
  		STAB[i] = (uint32_t)zero_seg - STAB2VIRT(i);
  
  	/* 
  	 * the lower 3G of the address space are considered unmapped, and
  	 * hence they translate to null_seg (i.e., reading/writing from an
  	 * unmapped address will fail)
  	 */
! 	for (i = VIRT2STAB(USER_START); i <= VIRT2STAB(STACK_SEG_ADDR - 1); i++)
  		STAB[i] = (uint32_t)null_seg - STAB2VIRT(i);
! 	
! 	/* 
! 	 * stack mapping
! 	 */
! 	for (i = VIRT2STAB(STACK_SEG_ADDR), j = 0;
! 			i <= VIRT2STAB(USER_END); i++, j++)
! 		STAB[i] = (uint32_t)stack_seg - STAB2VIRT(i) + (j * PAGE_SZ);
! 	
  	/* try to get the vDSO address */
  	get_vdso(&vdso_start, &vdso_end);
  		
--- 527,553 ----
  	for (i = VIRT2STAB(KERN_START); i <= VIRT2STAB(KERN_END); i++)
  		STAB[i] = (uint32_t)zero_seg - STAB2VIRT(i);
  
+ #ifdef DEBUG_MEMTRACK
+ 		/* verbose */
+ 		LOG(string(__func__) + ": kernel range " + hexstr(KERN_START) + "-" + hexstr(KERN_END) + ": zero_seg\n");
+ 		LOG(string(__func__) + ": zero_seg is " +hexstr(zero_seg) + "\n");
+ 		LOG(string(__func__) + ": null_seg is " +hexstr(null_seg) + "\n");
+ #endif
+ 
  	/* 
  	 * the lower 3G of the address space are considered unmapped, and
  	 * hence they translate to null_seg (i.e., reading/writing from an
  	 * unmapped address will fail)
  	 */
! 	for (i = VIRT2STAB(USER_START); i <= VIRT2STAB(USER_END); i++)
  		STAB[i] = (uint32_t)null_seg - STAB2VIRT(i);
! 
! #ifdef DEBUG_MEMTRACK
! 		/* verbose */
! 		LOG(string(__func__) + ": user range " + hexstr(USER_START) + "-" + hexstr(USER_END) + ": null_seg\n");
! #endif
! 
! 
  	/* try to get the vDSO address */
  	get_vdso(&vdso_start, &vdso_end);
  		
***************
*** 513,518 ****
--- 568,576 ----
  					vdso_end - 1) + "]\n");
  #endif
  	}
+ 
+ 		LOG(string(__func__) +
+ 			": tagmap allocation went ok. hooking elf_load");
  	
  	/* register the ELF image load callback */
  	IMG_AddInstrumentFunction(elf_load, NULL);
***************
*** 532,540 ****
  	if (null_seg != NULL)
  		/* deallocate the null segment space */
  		(void)munmap(null_seg, PAGE_SZ);
- 	if (stack_seg != NULL)
- 		/* deallocate the stack segment space */
- 		(void)munmap(stack_seg, STACK_SZ);
  
  	/* return with failure */
  	return 1;
--- 590,595 ----
***************
*** 549,556 ****
--- 604,622 ----
  void PIN_FAST_ANALYSIS_CALL
  tagmap_setb(size_t addr, uint8_t color)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_setb(0x%x, 0x%02x): *(uint8_t *)(0x%x + STAB[0x%x]) = 0x%02x; STAB[0x%x] == 0x%x -> *(uint8_t *)(0x%x) = 0x%02x\n",
+ 			 addr, color, addr, VIRT2STAB(addr), color, VIRT2STAB(addr), STAB[VIRT2STAB(addr)], (addr + STAB[VIRT2STAB(addr)]), color);
+ 	fprintf(stderr, "STAB page is %x\n", (addr + STAB[VIRT2STAB(addr)]));
+ 	if((PAGE_ALIGN(addr) + STAB[VIRT2STAB(addr)]) == (uint32_t) zero_seg) { 
+ 		fprintf(stderr, "WARNING: holy shit setb to zero_seg\n");
+ 	}
+ #endif
  	/* tag the byte that corresponds to the given address */
  	*(uint8_t *)(addr + STAB[VIRT2STAB(addr)]) = color;
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "set done\n");
+ #endif
  }
  
  /*
***************
*** 561,566 ****
--- 627,641 ----
  void PIN_FAST_ANALYSIS_CALL
  tagmap_clrb(size_t addr)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_clrb(0x%x): *(uint8_t *)(0x%x + STAB[0x%x]) = TAG_ZERO; STAB[0x%x] == 0x%x -> *(uint8_t *)(0x%x) = TAG_ZERO\n",
+ 			 addr, addr, VIRT2STAB(addr), VIRT2STAB(addr), STAB[VIRT2STAB(addr)], (addr + STAB[VIRT2STAB(addr)]));
+ 	fprintf(stderr, "STAB page is %x\n", (addr + STAB[VIRT2STAB(addr)]));
+ 	if((PAGE_ALIGN(addr) + STAB[VIRT2STAB(addr)]) == (uint32_t) zero_seg) { 
+ 		fprintf(stderr, "WARNING: ignoring clrb to zero_seg\n");
+ 		return;
+ 	}
+ #endif
  	/* clear the byte that corresponds to the given address */
  	*(uint8_t *)(addr + STAB[VIRT2STAB(addr)]) = TAG_ZERO;
  }
***************
*** 575,580 ****
--- 650,660 ----
  uint8_t
  tagmap_getb(size_t addr)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_getb(0x%x): return *(uint8_t *)(0x%x + STAB[0x%x]); STAB[0x%x] == 0x%x -> return *(uint8_t *)(0x%x)\n",
+ 			 addr, addr, VIRT2STAB(addr), VIRT2STAB(addr), STAB[VIRT2STAB(addr)], (addr + STAB[VIRT2STAB(addr)]));
+ 	fprintf(stderr, "STAB page is %x\n", (addr + STAB[VIRT2STAB(addr)]));
+ #endif
  	/* get the byte that corresponds to the address */
  	return *(uint8_t *)(addr + STAB[VIRT2STAB(addr)]);
  }
***************
*** 588,595 ****
--- 668,685 ----
  void PIN_FAST_ANALYSIS_CALL
  tagmap_setw(size_t addr, uint16_t color)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_setw(0x%x)\n", addr);
+ 	fprintf(stderr, "STAB page is %x\n", (addr + STAB[VIRT2STAB(addr)]));
+ 	if((PAGE_ALIGN(addr) + STAB[VIRT2STAB(addr)]) == (uint32_t) zero_seg) { 
+ 		fprintf(stderr, "WARNING: holy shit setw to zero_seg\n");
+ 	}
+ #endif
  	/* tag the bytes that correspond to the addresses of the word */
  	*(uint16_t *)(addr + STAB[VIRT2STAB(addr)]) = color;
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "set done\n");
+ #endif
  }
  
  /*
***************
*** 600,607 ****
--- 690,709 ----
  void PIN_FAST_ANALYSIS_CALL
  tagmap_clrw(size_t addr)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_clrw(0x%x): *(uint16_t *)(0x%x + STAB[0x%x]) = TAG_ZERO; STAB[0x%x] == 0x%x -> *(uint16_t *)(0x%x) = TAG_ZERO\n",
+ 			 addr, addr, VIRT2STAB(addr), VIRT2STAB(addr), STAB[VIRT2STAB(addr)], (addr + STAB[VIRT2STAB(addr)]));
+ 	fprintf(stderr, "STAB page is %x\n", (PAGE_ALIGN(addr) + STAB[VIRT2STAB(addr)]));
+ 	if((PAGE_ALIGN(addr) + STAB[VIRT2STAB(addr)]) == (uint32_t) zero_seg) { 
+ 		fprintf(stderr, "WARNING: ignoring clrw to zero_seg\n");
+ 		return;
+ 	}
+ #endif
  	/* clear the bytes that correspond to the addresses of the word */
  	*(uint16_t *)(addr + STAB[VIRT2STAB(addr)]) = TAG_ZERO;
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_clrw done\n");
+ #endif
  }
  
  /*
***************
*** 614,619 ****
--- 716,724 ----
  uint16_t
  tagmap_getw(size_t addr)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "line %d: STAB page is %x, returning it\n", __LINE__, (addr + STAB[VIRT2STAB(addr)]));
+ #endif
  	/* get the bytes that correspond to the addresses of the word */
  	return *(uint16_t *)(addr + STAB[VIRT2STAB(addr)]);
  }
***************
*** 627,634 ****
--- 732,749 ----
  void PIN_FAST_ANALYSIS_CALL
  tagmap_setl(size_t addr, uint32_t color)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_setl(0x%x)\n", addr);
+ 	fprintf(stderr, "STAB page is %x\n", (addr + STAB[VIRT2STAB(addr)]));
+ 	if((PAGE_ALIGN(addr) + STAB[VIRT2STAB(addr)]) == (uint32_t) zero_seg) { 
+ 		fprintf(stderr, "WARNING: holy shit setl to zero_seg\n");
+ 	}
+ #endif
  	/* tag the bytes that correspond to the addresses of the long word */
  	*(uint32_t *)(addr + STAB[VIRT2STAB(addr)]) = color;
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "set done\n");
+ #endif
  }
  
  /*
***************
*** 639,646 ****
--- 754,773 ----
  void PIN_FAST_ANALYSIS_CALL
  tagmap_clrl(size_t addr)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_clrl(0x%x): *(uint32_t *)(0x%x + STAB[0x%x]) = TAG_ZERO; STAB[0x%x] == 0x%x -> *(uint32_t *)(0x%x) = TAG_ZERO\n",
+ 			 addr, addr, VIRT2STAB(addr), VIRT2STAB(addr), STAB[VIRT2STAB(addr)], (addr + STAB[VIRT2STAB(addr)]));
+ 	fprintf(stderr, "STAB page is %x\n", (addr + STAB[VIRT2STAB(addr)]));
+ 	if((PAGE_ALIGN(addr) + STAB[VIRT2STAB(addr)]) == (uint32_t) zero_seg) { 
+ 		fprintf(stderr, "WARNING: ignoring clrl to zero_seg\n");
+ 		return;
+ 	}
+ #endif
  	/* clear the bytes that correspond to the addresses of the long word */
  	*(uint32_t *)(addr + STAB[VIRT2STAB(addr)]) = TAG_ZERO;
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "set done\n");
+ #endif
  }
  
  /*
***************
*** 653,658 ****
--- 780,788 ----
  uint32_t PIN_FAST_ANALYSIS_CALL
  tagmap_getl(size_t addr)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "line %d: STAB page is %x, returning it\n", __LINE__, (addr + STAB[VIRT2STAB(addr)]));
+ #endif
  	/* get the bytes that correspond to the addresses of the long word */
  	return *(uint32_t *)(addr + STAB[VIRT2STAB(addr)]);
  }
***************
*** 666,673 ****
--- 796,813 ----
  void
  tagmap_setn(size_t addr, size_t num, uint8_t color)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_setn(0x%x)\n", addr);
+ 	fprintf(stderr, "STAB page is %x\n", (addr + STAB[VIRT2STAB(addr)]));
+ 	if((PAGE_ALIGN(addr) + STAB[VIRT2STAB(addr)]) == (uint32_t) zero_seg) { 
+ 		fprintf(stderr, "WARNING: holy shit setn to zero_seg\n");
+ 	}
+ #endif
  	/* tag the bytes that correspond to the addresses of the num bytes */
  	(void)memset((void *)(addr + STAB[VIRT2STAB(addr)]), color, num);
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "set done\n");
+ #endif
  }
  
  /*
***************
*** 679,684 ****
--- 819,831 ----
  void
  tagmap_clrn(size_t addr, size_t num)
  {
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "tagmap_clrn(0x%x)\n", addr);
+ 	fprintf(stderr, "STAB page is %x\n", (addr + STAB[VIRT2STAB(addr)]));
+ #endif
  	/* clear the bytes that correspond to the addresses of the num bytes */
  	(void)memset((void *)(addr + STAB[VIRT2STAB(addr)]), TAG_ZERO, num);
+ #ifdef DEBUG_TAGMAP
+ 	fprintf(stderr, "set done\n");
+ #endif
  }
diff -crB libdft-ng_linux-i386.orig/tools/libdft-dta.c libdft-ng_linux-i386.patched/tools/libdft-dta.c
*** libdft-ng_linux-i386.orig/tools/libdft-dta.c	2013-03-15 20:20:08.000000000 +0100
--- libdft-ng_linux-i386.patched/tools/libdft-dta.c	2018-08-16 14:41:41.023967646 +0200
***************
*** 39,44 ****
--- 39,46 ----
  
  #include <errno.h>
  #include <sys/socket.h>
+ #include <sys/types.h>
+ #include <unistd.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
diff -crB libdft-ng_linux-i386.orig/tools/Makefile libdft-ng_linux-i386.patched/tools/Makefile
*** libdft-ng_linux-i386.orig/tools/Makefile	2013-03-15 20:20:08.000000000 +0100
--- libdft-ng_linux-i386.patched/tools/Makefile	2018-08-16 14:41:41.067967847 +0200
***************
*** 38,44 ****
  
  # get system information
  OS=$(shell uname -o | grep Linux$$)			# OS
! ARCH=$(shell uname -m | grep 86$$)			# arch
  
  # default target (build libdft only)
  all: sanity tools
--- 38,45 ----
  
  # get system information
  OS=$(shell uname -o | grep Linux$$)			# OS
! #ARCH=$(shell uname -m | grep 86$$)			# arch
! ARCH=$(shell uname -m | grep "x86_64\|86$$")
  
  # default target (build libdft only)
  all: sanity tools
***************
*** 55,61 ****
  endif
  # check the architecture (must be x86, i386, i486, i686, ...)
  ifeq ($(strip $(ARCH)),)
! 	$(error "This version of libdft is for x86 only")
  endif
  
  
--- 56,68 ----
  endif
  # check the architecture (must be x86, i386, i486, i686, ...)
  ifeq ($(strip $(ARCH)),)
! 	$(error "This version of libdft is for x86 and x86_64 only")
! endif
! 
! # check need for cross-compile.
! ifeq ($(findstring "x86_64", $(ARCH)),)
! CXXFLAGS += -m32 
! CXXFLAGS_SO += -m32
  endif
  
  
