diff --git a/Make-Android b/Make-Android
new file mode 100755
index 0000000..d3c571a
--- /dev/null
+++ b/Make-Android
@@ -0,0 +1,16 @@
+#!/bin/sh
+FILES="dd_rescue libddr_crypt.so  libddr_lzo.so  libddr_null.so libddr_hash.so file_zblock fmt_no sha1 sha256 sha512 md5 test_aes fiemap find_nonzero fuzz_lzo"
+
+make_and()
+{
+	mkdir -p $2
+	make clean
+	make -f $1 config; make -f $1 all -j4
+	for name in $FILES; do mv $name $2/; done
+}
+
+make_and Makefile.android.arm32 android.arm32
+make_and Makefile.android.arm32pie android.arm32pie
+make_and Makefile.android.arm64 android.arm64
+make clean
+
diff --git a/Makefile b/Makefile
index f891255..4c74108 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 # (c) garloff@suse.de, 99/10/09, GNU GPL
 # (c) kurt@garloff.de, 2010 -- 2015, GNU GPL v2 or v3
 
-VERSION = 1.99
+VERSION = 1.99.4
 
 DESTDIR = 
 
@@ -38,6 +38,7 @@ OUT = -o dd_rescue
 PIC = -fPIC
 PIE = -fPIE
 LDPIE = -pie
+RDYNAMIC = -rdynamic
 
 LZOP = $(shell type -p lzop || type -P true)
 HAVE_SHA256SUM = $(shell type -p sha256sum >/dev/null && echo 1 || echo 0)
@@ -66,15 +67,30 @@ ifeq ($(CC),wcl386)
   OUT = ""
 endif
 
-HAVE_AVX2 := $(shell echo "" | $(CC) -mavx2 -xc - 2>&1 | grep unrecognized || echo 1)
-HAVE_SSE42 := $(shell echo "" | $(CC) -msse4.2 -xc - 2>&1 | grep unrecognized || echo 1)
-HAVE_RDRNDAES := $(shell echo "" | $(CC) -mrdrnd -maes -xc - 2>&1 | grep unrecognized || echo 1)
+MACH := $(shell uname -m | tr A-Z a-z | sed 's/i[3456]86/i386/')
 
-ifneq ($(HAVE_RDRNDAES),1)
-	HAVE_RDRNDAES = 0
+ISX86 := 0
+ifeq ($(MACH),i386)
+  ISX86 := 1
+endif
+ifeq ($(MACH),x86_64)
+  ISX86 := 1
+  LIB = lib64
 endif
 
-MACH := $(shell uname -m | tr A-Z a-z | sed 's/i[3456]86/i386/')
+ifeq ($(ISX86), 1)
+HAVE_SSE42 := $(shell echo "" | $(CC) -msse4.2 -xc - 2>&1 | grep unrecognized || echo 1)
+HAVE_AES := $(shell echo "" | $(CC) -maes -xc - 2>&1 | grep unrecognized || echo 1)
+HAVE_AVX2 := $(shell echo "" | $(CC) -mavx2 -xc - 2>&1 | grep unrecognized || echo 1)
+HAVE_RDRND := $(shell echo "" | $(CC) -mrdrnd -xc - 2>&1 | grep unrecognized || echo 1)
+endif
+
+ifneq ($(HAVE_RDRND),1)
+	HAVE_RDRND = 0
+endif
+ifneq ($(HAVE_AES),1)
+	HAVE_AES = 0
+endif
 
 
 ifeq ($(MACH),i386)
@@ -82,70 +98,56 @@ ifeq ($(MACH),i386)
 	#SSE = "-msse2 -funroll-loops"
 	#SSE = "-msse2 -funroll-loops -ftree-vectorize"
 	ARCHFLAGS +=  -msse2
-	OBJECTS2 = find_nonzero_sse2.o 
-ifeq ($(HAVE_SSE42),1)
-	OBJECTS2 += ffs_sse42.o
-	ARCHFLAGS +=  -msse4.2
-else
-	CFLAGS += -DNO_SSE42
-endif
-ifeq ($(HAVE_AVX2),1)
-	OBJECTS2 += find_nonzero_avx.o
-	ARCHFLAGS +=  -mavx2
-else
-	CFLAGS += -DNO_AVX2
-endif
-ifeq ($(HAVE_RDRNDAES),1)
-	OBJECTS2 += rdrand.o
-	POBJECTS2 += rdrand.po
-	AESNI_O = aesni.o
-	AESNI_PO = aesni.po
-	CFLAGS += -DHAVE_AESNI
-	ARCHFLAGS +=  -maes -mrdrnd
-else
-	CFLAGS += -DNO_RDRND -DNO_AES
-endif
 endif
 
-ifeq ($(MACH),x86_64)
-	LIB = lib64
+ifeq ($(ISX86),1)
 	OBJECTS2 = find_nonzero_sse2.o
+
 ifeq ($(HAVE_SSE42),1)
 	OBJECTS2 += ffs_sse42.o
+	#POBJECTS2 += ffs_sse42.po
 	ARCHFLAGS +=  -msse4.2
 else
 	CFLAGS += -DNO_SSE42
 endif
+ifeq ($(HAVE_AES),1)
+	AESNI_O = aesni.o
+        AESNI_PO = aesni.po
+	OBJECTS2 += rdrand.o
+	#POBJECTS2 += rdrand.po find_nonzero.po ffs_sse42.po
+        CFLAGS += -DHAVE_AESNI
+	ARCHFLAGS += -maes
+else
+	CFLAGS += -DNO_AES
+endif
 ifeq ($(HAVE_AVX2),1)
 	OBJECTS2 += find_nonzero_avx.o
 	ARCHFLAGS +=  -mavx2
 else
 	CFLAGS += -DNO_AVX2
 endif
-ifeq ($(HAVE_RDRNDAES),1)
-	OBJECTS2 += rdrand.o
-	POBJECTS2 += rdrand.po
-	AESNI_O = aesni.o
-	AESNI_PO = aesni.po
-	CFLAGS += -DHAVE_AESNI
-	ARCHFLAGS +=  -maes -mrdrnd
+ifeq ($(HAVE_RDRND),1)
+	#OBJECTS2 += rdrand.o
+	#POBJECTS2 += rdrand.po
+	ARCHFLAGS +=  -mrdrnd
 else
-	CFLAGS += -DNO_RDRND -DNO_AES
+	CFLAGS += -DNO_RDRND 
 endif
 endif
 
 MACH := $(shell uname -m |sed 's/armv[0-9a-z]*/arm/')
 ifeq ($(MACH),arm)
 	OBJECTS2 = find_nonzero_arm.o
-	POBJECTS2 = find_nonzero_arm.po
+	#POBJECTS2 = find_nonzero.po find_nonzero_arm.po
 	AES_ARM64_O = aes_arm32.o
 	AES_ARM64_PO = aes_arm32.po
 	CFLAGS += -DHAVE_AES_ARM64
 	ARCHFLAGS += -mfpu=crypto-neon-fp-armv8
 endif
 ifeq ($(MACH),aarch64)
+	LIB = lib64
 	OBJECTS2 = find_nonzero_arm64.o
-	POBJECTS2 = find_nonzero_arm64.po
+	#POBJECTS2 = find_nonzero.po find_nonzero_arm64.po
 	AES_ARM64_O = aes_arm64.o
 	AES_ARM64_PO = aes_arm64.po
 	CFLAGS += -DHAVE_AES_ARM64
@@ -235,7 +237,7 @@ libddr_lzo.so: libddr_lzo.po
 libddr_null.so: libddr_null.po
 	$(CC) -shared -o $@ $^
 
-libddr_crypt.so: libddr_crypt.po aes.po aes_c.po $(AESNI_PO) $(AES_ARM64_PO) $(AES_OSSL_PO) pbkdf2.po sha256.po pbkdf_ossl.po md5.po checksum_file.po secmem.po random.po find_nonzero.po $(POBJECTS2)
+libddr_crypt.so: libddr_crypt.po aes.po aes_c.po $(AESNI_PO) $(AES_ARM64_PO) $(AES_OSSL_PO) pbkdf2.po sha256.po pbkdf_ossl.po md5.po checksum_file.po secmem.po random.po $(POBJECTS2)
 	$(CC) -shared -o $@ $^ $(CRYPTOLIB) $(EXTRA_LDFLAGS)
 
 # More special compiler flags
@@ -266,23 +268,34 @@ find_nonzero_main.o: find_nonzero.c config.h $(FNZ_HEADERS)
 ffs_sse42.o:
 	$(CC) $(CFLAGS_OPT) $(PIE) -msse4.2 -c $<
 
+ffs_sse42.po:
+	$(CC) $(CFLAGS_OPT) $(PIC) -msse4.2 -o $@ -c $<
+
+ifeq ($(HAVE_RDRND),1)
 rdrand.o:
 	$(CC) $(CFLAGS) $(PIE) -mrdrnd -maes -c $<
 
 rdrand.po:
 	$(CC) $(CFLAGS) $(PIC) -mrdrnd -maes -o $@ -c $<
+else
+rdrand.o:
+	$(CC) $(CFLAGS) $(PIE) -maes -c $<
+
+rdrand.po:
+	$(CC) $(CFLAGS) $(PIC) -maes -o $@ -c $<
+endif
 
 # TODO: Build binaries from .o file, so we can save some special rules ...
 # Special dd_rescue variants
 libfalloc: dd_rescue.c $(DDR_HEADERS) $(OBJECTS) $(OBJECTS2)
-	$(CC) $(CFLAGS) $(PIE) $(LDPIE) -DNO_LIBDL $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) -lfallocate $(EXTRA_LDFLAGS)
+	$(CC) $(CFLAGS) $(PIE) $(LDPIE) -DNO_LIBDL $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) -lfallocate $(EXTRA_LDFLAGS) $(RDYNAMIC)
 
 libfalloc-static: dd_rescue.c $(DDR_HEADERS) $(OBJECTS) $(OBJECTS2)
-	$(CC) $(CFLAGS) $(PIE) $(LDPIE) -DNO_LIBDL $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) $(LIBDIR)/libfallocate.a $(EXTRA_LDFLAGS)
+	$(CC) $(CFLAGS) $(PIE) $(LDPIE) -DNO_LIBDL $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) $(LIBDIR)/libfallocate.a $(EXTRA_LDFLAGS) $(RDYNAMIC)
 
 # This is the default built
 dd_rescue: dd_rescue.c $(DDR_HEADERS) $(OBJECTS) $(OBJECTS2)
-	$(CC) $(CFLAGS) $(PIE) $(LDPIE) $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) -ldl $(EXTRA_LDFLAGS)
+	$(CC) $(CFLAGS) $(PIE) $(LDPIE) $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) -ldl $(EXTRA_LDFLAGS) $(RDYNAMIC)
 
 # Test programs 
 md5: md5.c md5.h hash.h config.h
@@ -313,7 +326,7 @@ nolib: dd_rescue.c $(DDR_HEADERS) $(OBJECTS) $(OBJECTS2)
 	$(CC) $(CFLAGS) -DNO_LIBDL -DNO_LIBFALLOCATE $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2)
 
 nocolor: dd_rescue.c $(DDR_HEADERS) $(OBJECTS) $(OBJECTS2)
-	$(CC) $(CFLAGS) -DNO_COLORS=1 $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) $(EXTRA_LDFLAGS)
+	$(CC) $(CFLAGS) -DNO_COLORS=1 $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) $(EXTRA_LDFLAGS) $(RDYNAMIC)
 
 static: dd_rescue.c $(DDR_HEADERS) $(OBJECTS)
 	$(CC) $(CFLAGS) -DNO_LIBDL -DNO_LIBFALLOCATE -static $(DEFINES) $< $(OUT) $(OBJECTS) $(OBJECTS2) $(EXTRA_LDFLAGS)
@@ -399,11 +412,13 @@ install: $(TARGETS)
 	$(INSTALL) $(INSTASROOT) -m 644 dd_rescue.1 ddr_lzo.1 ddr_crypt.1 $(MANDIR)/man1/
 	gzip -9f $(MANDIR)/man1/dd_rescue.1 $(MANDIR)/man1/ddr_lzo.1 $(MANDIR)/man1/ddr_crypt.1
 
-check: $(TARGETS) find_nonzero md5 sha1 sha256 sha512
+check: $(TARGETS) find_nonzero md5 sha1 sha256 sha512 fmt_no
 	@echo "make check ... Pass VG=\"valgrind --options\" to use with valgrind"
 	$(VG) ./dd_rescue --version
 	@echo "***** find_nonzero tests *****"
 	$(VG) ./find_nonzero 2
+	@echo "***** fmt_no tests *****"
+	$(VG) ./fmt_no 1024200
 	@echo "***** dd_rescue tests *****"
 	@rm -f dd_rescue.copy dd_rescue.copy2
 	$(VG) ./dd_rescue -apP dd_rescue dd_rescue.copy
@@ -419,6 +434,8 @@ check: $(TARGETS) find_nonzero md5 sha1 sha256 sha512
 	cmp dd_rescue.copy dd_rescue.copy2
 	@rm dd_rescue.copy dd_rescue.copy2
 	@rm -f zero zero2
+	$(VG) ./dd_rescue -r -S 1M -m 4k /dev/null zero
+	@rm -f zero
 	@echo "***** dd_rescue sparse tests *****"
 	$(VG) ./dd_rescue -a -m 261k /dev/zero zero
 	du zero
@@ -436,6 +453,7 @@ check: $(TARGETS) find_nonzero md5 sha1 sha256 sha512
 	@echo "***** dd_rescue MD5 plugin tests *****"
 	$(VG) ./md5 /dev/null
 	$(VG) ./md5 /dev/null | md5sum -c
+	$(VG) ./dd_rescue -a -b 16k -l TEST.log -o BB.log -m 32k /dev/zero TEST
 	$(VG) ./dd_rescue -a -b 16k -m 32k /dev/zero TEST
 	$(VG) ./dd_rescue -x -a -b 16k -m32k dd_rescue TEST
 	$(VG) ./dd_rescue -x -a -b 16k -m17k /dev/zero TEST
@@ -450,7 +468,7 @@ check: $(TARGETS) find_nonzero md5 sha1 sha256 sha512
 	if test $(HAVE_SHA256SUM) = 1; then $(MAKE) check_sha2; fi
 	$(VG) ./sha256 /dev/null
 	$(VG) ./sha512 /dev/null
-	rm -f TEST TEST2 HASH.TEST
+	rm -f TEST TEST2 HASH.TEST BB.log TEST.log
 	if test $(HAVE_LZO) = 1; then $(MAKE) check_lzo; fi
 	if test $(HAVE_LZO) = 1; then $(MAKE) check_lzo_algos; fi
 	#if test $(HAVE_LZO) = 1; then $(MAKE) check_lzo_test; fi
@@ -594,7 +612,7 @@ check_aes: $(TARGETS) test_aes
 
 check_crypt: $(TARGETS)
 	# TODO: Move previous cases into script ...
-	HAVE_LZO=$(HAVE_LZO) HAVE_OPENSSL=$(HAVE_OPENSSL) HAVE_RDRNDAES=$(HAVE_RDRNDAES) ./test_crypt.sh
+	HAVE_LZO=$(HAVE_LZO) HAVE_OPENSSL=$(HAVE_OPENSSL) HAVE_AES=$(HAVE_AES) ./test_crypt.sh
 	# Holes (all)
 	# Reverse (CTR, ECB)
 	# Chain with lzo, hash (all)
@@ -610,6 +628,7 @@ check_fault: $(TARGETS)
 	$(VG) ./dd_rescue -tpv -F 4r/1,6r/1,22r/1 dd_rescue dd_rescue.cmp || true
 	cmp dd_rescue dd_rescue.cmp
 	# Incremental
+	$(VG) ./dd_rescue -tp -F 4r/0,20r/0 -l dd_r.log -o dd_r.bb dd_rescue dd_rescue.cmp || true
 	$(VG) ./dd_rescue -tp -F 4r/0,20r/0 dd_rescue dd_rescue.cmp || true
 	cmp dd_rescue dd_rescue.cmp || true
 	$(VG) ./dd_rescue -p -F 6r/0 dd_rescue dd_rescue.cmp || true
@@ -629,6 +648,7 @@ check_fault: $(TARGETS)
 	# - encryption (check_crypt)
 	# - compression
 	# - checksums
+	rm -f dd_rescue.cmp dd_r.log dd_r.bb
 
 
 make_check_crypt: check_crypt
@@ -646,5 +666,7 @@ make_check_crypt: check_crypt
 	$(VG) ./dd_rescue -tp -L ./libddr_crypt.so=dec:keysfile:ivsfile:alg=AES192+-CTR dd_rescue.enc dd_rescue.dec
 	cat dd_rescue dd_rescue > dd_rescue2
 	cmp dd_rescue2 dd_rescue.dec
+	# Cleanup
+	rm -f dd_rescue2 dd_rescue.dec dd_rescue.enc
 
 
diff --git a/aesni.c b/aesni.c
index 26a3fb0..177b4fa 100644
--- a/aesni.c
+++ b/aesni.c
@@ -17,7 +17,7 @@
 #ifdef DONTMASK
 #define MMCLEAR(xmmreg) xmmreg = _mm_setzero_si128()
 #else
-#define MMCLEAR(xmmreg) asm volatile ("pxor %0, %0 \n" : "=x"(xmmreg): "0"(xmmreg):)
+#define MMCLEAR(xmmreg) asm volatile ("pxor %0, %0 \n" : "=x"(xmmreg): "0"(xmmreg))
 #endif
 
 #define SIZE128 (ssize_t)sizeof(__m128i)
diff --git a/archdep.h b/archdep.h
index d1a682c..5da2ca5 100644
--- a/archdep.h
+++ b/archdep.h
@@ -24,7 +24,7 @@ void probe_sse2();
 #define ARCH_DETECT_386
 #endif
 
-#ifdef NO_SSE42	/* compiler does not support -msse4.2 (nor -mavx2) */
+#ifdef NO_SSE42		/* compiler does not support -msse4.2 (nor -mavx2) */
 #define have_avx2 0
 #define have_sse42 0
 #define have_rdrand 0
@@ -32,37 +32,49 @@ void probe_sse2();
 #define ARCH_DETECT do {} while (0)
 #define ARCH_DECLS ARCH_DECL_386
 
-#elif defined(NO_AVX2) /* compiler does not support -mavx2 */
+#else 	/* We have SSE4.2 */
+extern char have_sse42;
+void probe_sse42();
+
+#ifdef NO_AESNI		/* compiler does not support -maes */
 #define have_avx2 0
 #define have_rdrand 0
 #define have_aesni 0
-extern char have_sse42;
-void probe_sse42();
 #define ARCH_DECLS char have_sse42; ARCH_DECL_386
 #define ARCH_DETECT have_sse42 = detect("sse4.2", probe_sse42) ARCH_DETECT_386
 
-#else /* compiler supports both extensions */
+#else	/* We have AESNI, yeah! */
+extern char have_aesni;
+void probe_aesni();
+
+#ifdef NO_AVX2	/* compiler does not support -mavx2 */
+#define have_avx2 0
+#define have_rdrand 0
+#define ARCH_DECLS char have_sse42; char have_aesni; ARCH_DECL_386
+#define ARCH_DETECT have_aesni = detect2("aes", probe_aesni); have_sse42 = detect("sse4.2", probe_sse42) \
+		    ARCH_DETECT_386
+
+#else	/* We have avx2 */
 extern char have_avx2;
-extern char have_sse42;
+void probe_avx2();
 
-#ifdef NO_RDRND	/* SSE42 and AVX2 but no rdrand+aesni */
+#ifdef NO_RDRND	/* SSE42 and AESNI and AVX2 but no rdrand */
 #define have_rdrand 0
-#define have_aesni 0
-void probe_avx2(); void probe_sse42();
-#define ARCH_DECLS char have_avx2; char have_sse42; ARCH_DECL_386
-#define ARCH_DETECT have_avx2 = detect("avx2", probe_avx2); have_sse42 = detect("sse4.2", probe_sse42) \
-			ARCH_DETECT_386
+#define ARCH_DECLS char have_avx2; char have_aesni; char have_sse42; ARCH_DECL_386
+#define ARCH_DETECT have_avx2 = detect("avx2", probe_avx2); have_aesni = detect2("aes", probe_aesni); \
+		    have_sse42 = detect("sse4.2", probe_sse42) ARCH_DETECT_386
 
 #else /* Probe everything */
 extern char have_rdrand;
-extern char have_aesni;
-void probe_avx2(); void probe_sse42(); void probe_rdrand(); void probe_aesni();
-#define ARCH_DECLS char have_aesni; char have_rdrand; char have_avx2; char have_sse42; ARCH_DECL_386
-#define ARCH_DETECT have_avx2 = detect("avx2", probe_avx2); have_sse42 = detect("sse4.2", probe_sse42); \
-			have_rdrand = detect2("rdrand", probe_rdrand); have_aesni = detect2("aes", probe_aesni) \
-			ARCH_DETECT_386
-#endif	/* RDRND / AESNI */
-#endif	/* SSE42 / AVX2 */
+void probe_rdrand();
+#define ARCH_DECLS char have_rdrand; char have_avx2; char have_aesni; char have_sse42; ARCH_DECL_386
+#define ARCH_DETECT have_rdrand = detect2("rdrand", probe_rdrand); have_avx2 = detect("avx2", probe_avx2); \
+		    have_aesni = detect2("aes", probe_aesni); have_sse42 = detect("sse4.2", probe_sse42) \
+		    ARCH_DETECT_386
+#endif	/* RDRND */
+#endif	/* AVX2 */
+#endif	/* AESNI */
+#endif	/* SSE42 */
 
 #define FIND_NONZERO_OPT(x,y) (have_avx2? find_nonzero_avx2(x,y): (have_sse2? find_nonzero_sse2(x,y): find_nonzero_c(x,y)))
 #define OPT_STR (have_avx2? "avx2": (have_sse42? "sse4.2": (have_sse2? "sse2": "c")))
diff --git a/dd_rescue.c b/dd_rescue.c
index 6d6b7f1..eba717e 100644
--- a/dd_rescue.c
+++ b/dd_rescue.c
@@ -194,8 +194,17 @@ void* libfalloc = (void*)0;
 
 #define MIN(a,b) ((a)<(b)? (a): (b))
 
+#if __WORDSIZE == 64
+#define LL "l"
+#elif __WORDSIZE == 32
+#define LL "ll"
+#else
+#error __WORDSIZE undefined
+#endif
+
+
 /* fwd decls */
-int cleanup();
+int cleanup(char);
 
 struct emerg_ptrs {
 	opt_t *opts;
@@ -271,7 +280,7 @@ const char* threeup = UP UP UP;
 //const char* down = DOWN;
 const char* right = RIGHT;
 const char* nineright = RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT;
-char *graph;
+char *graph;	/* = NULL */
 
 #ifdef NO_COLORS
 # define RED ""
@@ -712,7 +721,7 @@ static int openfile(const char* const fname, const int flags)
 	if (fdes == -1) {
 		fplog(stderr, FATAL, "open \"%s\" failed: %s\n",
 			fname, strerror(errno));
-		cleanup(); exit(17);
+		cleanup(1); exit(17);
 	}
 	return fdes;
 }
@@ -739,11 +748,14 @@ inline int gpos(loff_t off, loff_t len)
 }
 
 /** Prepare graph */
+static char *sgraph = ":.........................................:";
 static void preparegraph(opt_t *op, fstate_t *fst)
 {
 	if (!fst->ilen || op->init_ipos > fst->ilen)
 		return;
-	graph = strdup(":.........................................:");
+	if (op->reverse && op->init_ipos-fst->estxfer < 0)
+		return;
+	graph = strdup(sgraph);
 	if (op->reverse) {
 		graph[gpos(op->init_ipos, fst->ilen)+1] = '<';
 		graph[gpos(op->init_ipos-fst->estxfer, fst->ilen)-1] = '>';
@@ -756,10 +768,9 @@ static void preparegraph(opt_t *op, fstate_t *fst)
 
 void updgraph(int err, fstate_t *fst, dpopt_t *dop)
 {
-	int off;
-	if (!fst->ilen || fst->ipos > fst->ilen)
+	if (!graph)
 		return;
-	off = gpos(fst->ipos, fst->ilen);
+	const int off = gpos(fst->ipos, fst->ilen);
 	if (graph[off] == 'x')
 		return;
 	if (err)
@@ -780,8 +791,13 @@ void input_length(opt_t *op, fstate_t *fst)
 	if (op->reverse) {
 		if (op->init_ipos)
 			fst->ilen = op->init_ipos;
-		else
+		else {
+			/* FIXME: Shouldn't we set ilen to 0
+			 * at least if !i_chr ?
+			 * Or otherwise correct init_ipos with a warning? */
+			fplog(stderr, WARN, "reverse copy from input file with offset 0\n");
 			fst->ilen = op->maxxfer;
+		}
 	} else
 		fst->ilen = op->init_ipos + op->maxxfer;
 	if (fst->estxfer)
@@ -875,8 +891,7 @@ int output_length(opt_t *op, fstate_t *fst)
 		loff_t newmax = fst->olen - op->init_opos;
 		if (newmax < 0) {
 			fplog(stderr, FATAL, "output position is beyond end of file but -M specified!\n");
-			cleanup();
-			exit(19);
+			cleanup(1); exit(19);
 		}			
 		if (!op->maxxfer || op->maxxfer > newmax) {
 			op->maxxfer = newmax;
@@ -1016,8 +1031,8 @@ void doprint(FILE* const file, const unsigned int bs, const clock_t cl,
 		sec = sec % 60;
 		updgraph(0, fst, dop);
 		fprintf(file, "             %s %3i%%  %s: %2i:%02i:%02i \n",
-			graph, (int)(100*prg->xfer/fst->estxfer), (in_report? "TOT": "ETA"), 
-			hour, min, sec);
+			graph? graph: sgraph, (int)(100*prg->xfer/fst->estxfer),
+			(in_report? "TOT": "ETA"), hour, min, sec);
 		scrollup = fourup;
 	} else
 		scrollup = threeup;
@@ -1047,6 +1062,12 @@ void printstatus(FILE* const file1, FILE* const file2,
 	t2 = difftimetv(&currenttime, &lasttime);
 	cl = clock();
 
+#if 0
+	if (t1 == 0.0)
+		t1 = 0.0001;
+	if (t2 == 0.0)
+		t2 = 0.0001;
+#endif
 	/* Idea: Could save last not printed status and print on err */
 	if (t2 < printint && !sync && !in_report) {
 		if (fst->estxfer)
@@ -1112,8 +1133,10 @@ void exit_report(int rc, opt_t *op, fstate_t *fst, progress_t *prg, dpopt_t *dop
 {
 	gettimeofday(&currenttime, NULL);
 	printreport(op, fst, prg, dop);
-	cleanup();
+	cleanup(0);
 	fplog(stderr, FATAL, "Not completed fully successfully! \n");
+	if (logfd)
+		fclose(logfd);
 	exit(rc);
 }
 
@@ -1279,7 +1302,7 @@ static void advancepos(const ssize_t rd, const ssize_t wr, const ssize_t rwr,
 		       opt_t *op, fstate_t *fst, progress_t *prg);
 
 int real_cleanup(opt_t *op, fstate_t *fst, progress_t *prg, 
-	 	 dpopt_t *dop, dpstate_t *dst)
+	 	 dpopt_t *dop, dpstate_t *dst, char closelog)
 {
 	int rc, errs = 0;
 	if (!op->dosplice && !dop->bsim715) {
@@ -1301,8 +1324,6 @@ int real_cleanup(opt_t *op, fstate_t *fst, progress_t *prg,
 			++errs;
 		}
 	}
-	if (logfd)
-		fclose(logfd);
 	LISTTYPE(ofile_t) *of;
 	LISTFOREACH(ofiles, of) {
 		ofile_t *oft = &(LISTDATA(of));
@@ -1340,17 +1361,23 @@ int real_cleanup(opt_t *op, fstate_t *fst, progress_t *prg,
 		LISTDATA(onl) = 0;
 	}
 	LISTTREEDEL(freenames, charp);
+	LISTTREEDEL(read_faults, fault_in_t);
+	LISTTREEDEL(write_faults, fault_in_t);
 #if USE_LIBDL
 	if (libfalloc)
 		dlclose(libfalloc);
 	unload_plugins();
 #endif
+	if (logfd && closelog) {
+		fclose(logfd);
+		logfd = 0;
+	}
 	return errs;
 }
 
-int cleanup()
+int cleanup(char closelog)
 {
-	return real_cleanup(eptrs.opts, eptrs.fstate, eptrs.progress, eptrs.dpopts, eptrs.dpstate);
+	return real_cleanup(eptrs.opts, eptrs.fstate, eptrs.progress, eptrs.dpopts, eptrs.dpstate, closelog);
 }
 
 int l2(unsigned int l)
@@ -1471,12 +1498,6 @@ static inline ssize_t mypread(int fd, void* bf, size_t sz, loff_t off,
 			      opt_t *op, fstate_t *fst, repeat_t *rep, 
 			      dpopt_t *dop, dpstate_t *dst)
 {
-	if (op->i_repeat) {
-		if (rep->i_rep_init)
-			return sz;
-		else
-			rep->i_rep_init = 1;
-	}
 	/* TODO: Handle plugin input here ... */
 	if (dop->prng_libc)
 		return fill_rand(bf, sz);
@@ -1504,6 +1525,13 @@ static inline ssize_t mypread(int fd, void* bf, size_t sz, loff_t off,
 		}
 		// Cloud read and return (fault-1)*op->hardbs bytes ...
 	}
+	/* Optimization for repeated read from same input */
+	if (op->i_repeat) {
+		if (rep->i_rep_init)
+			return sz;
+		else
+			rep->i_rep_init = 1;
+	}
 	/* We won't make progress beyond EOF */
 	ssize_t rd;
 	/* OK, regular read ... */
@@ -2280,21 +2308,21 @@ void init_random(opt_t *op, dpopt_t *dop, dpstate_t *dst)
 		if (fd == -1) {
 			fplog(stderr, FATAL, "Could not open \"%s\" for random seed!\n", dop->prng_sfile);
 			/* ERROR */
-			cleanup(); exit(28);
+			cleanup(1); exit(28);
 		}
 		if (dop->prng_libc) {
 			unsigned int* sval = (unsigned int*)sbf;
 			ln = read(fd, sbf, 4);
 			if (ln != 4) {
 				fplog(stderr, FATAL, "failed to read 4 bytes from \"%s\"!\n", dop->prng_sfile);
-				cleanup(); exit(29);
+				cleanup(1); exit(29);
 			}
 			srand(*sval); rand();
 		} else {
 			ln = read(fd, sbf, 256);
 			if (ln != 256) {
 				fplog(stderr, FATAL, "failed to read 256 bytes from \"%s\"!\n", dop->prng_sfile);
-				cleanup(); exit(29);
+				cleanup(1); exit(29);
 			}
 			dst->prng_state = frandom_init(sbf);
 		}
@@ -2494,7 +2522,7 @@ void breakhandler(int sig)
 		fplog(stderr, FATAL, "Caught signal %i \"%s\". Flush and exit immediately!\n",
 		      sig, strsignal(sig));
 		_printreport();
-		cleanup();
+		cleanup(1);
 		signal(sig, SIG_DFL);
 		raise(sig);
 	}
@@ -2522,7 +2550,7 @@ unsigned char* zalloc_aligned_buf(unsigned int bs, unsigned char**obuf)
 		if (!ptr) {
 			fplog(stderr, FATAL, "allocation of buffer of size %li failed!\n", 
 				bs+pagesize+plug_max_slack_pre+plug_max_slack_post);
-			cleanup(); exit(18);
+			cleanup(1); exit(18);
 		}
 		if (obuf)
 			*obuf = ptr;
@@ -2650,6 +2678,9 @@ void populate_faultlists(const char* arg, opt_t *op)
 			arg = ptr+1;
 		else
 			arg = arg+strlen(arg);
+		if (op->verbose)
+			fplog(stderr, DEBUG, "Inject %c fault (%ix) for range %" LL "u-%" LL "u\n",
+				rw, fault.rep, fault.off, fault.off2);
 	}
 	if (op->verbose)
 		fplog(stderr, DEBUG, "Will inject %i/%i faults for read/write\n",
@@ -2854,7 +2885,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 
 	if (fst->identical && op->dotrunc && !op->force) {
 		fplog(stderr, FATAL, "infile and outfile are identical and trunc turned on!\n");
-		cleanup(); exit(14);
+		cleanup(1); exit(14);
 	}
 
 	/* Open input and output files */
@@ -2866,7 +2897,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 		fst->ides = openfile(op->iname, O_RDONLY | op->o_dir_in);
 		if (fst->ides < 0) {
 			fplog(stderr, FATAL, "could not open %s: %s\n", op->iname, strerror(errno));
-			cleanup(); exit(22);
+			cleanup(1); exit(22);
 		}
 	}
 	/* Overwrite? */
@@ -2890,7 +2921,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 		} while (a != 'Y' && a != 'N');
 		if (a == 'N') {
 			fplog(stderr, FATAL, "exit on user request!\n");
-			cleanup(); exit(23);
+			cleanup(1); exit(23);
 		}
 	}
 	if (fst->o_chr && op->avoidwrite) {
@@ -2906,7 +2937,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 	/* Sanity checks for op->rmvtrim */
 	if ((fst->o_chr || fst->o_lnk || fst->o_blk) && op->rmvtrim) {
 		fplog(stderr, FATAL, "Can't delete output file when it's not a normal file\n");
-		cleanup(); exit(23);
+		cleanup(1); exit(23);
 	}
 
 	if (op->rmvtrim && !(op->i_repeat || dop->prng_libc || dop->prng_frnd || op->force)) {
@@ -2919,7 +2950,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 		if (a == 'N') {
 			fplog(stderr, FATAL, "exit on user request!\n");
 			op->rmvtrim = 0;
-			cleanup(); exit(23);
+			cleanup(1); exit(23);
 		}
 	}
 
@@ -2937,7 +2968,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 
 	if (fst->odes < 0) {
 		fplog(stderr, FATAL, "%s: %s\n", op->oname, strerror(errno));
-		cleanup(); exit(24);
+		cleanup(1); exit(24);
 	}
 
 	if (op->preserve)
@@ -2969,7 +3000,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 		op->init_ipos = lseek64(fst->ides, 0, SEEK_END);
 		if (op->init_ipos == -1) {
 			fplog(stderr, FATAL, "could not seek to end of file %s!\n", op->iname);
-			perror("dd_rescue"); cleanup(); exit(19);
+			perror("dd_rescue"); cleanup(1); exit(19);
 		}
 		if (op->verbose) 
 			fprintf(stderr, DDR_INFO "ipos set to the end: %skiB\n", 
@@ -2982,7 +3013,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 			op->init_opos = lseek64(fst->odes, 0, SEEK_END);
 			if (op->init_opos == (loff_t)-1) {
 				fplog(stderr, FATAL, "could not seek to end of file %s!\n", op->oname);
-				perror("dd_rescue"); cleanup(); exit(19);
+				perror("dd_rescue"); cleanup(1); exit(19);
 			}
 			/* if existing empty, assume same position */
 			if (op->init_opos == 0)
@@ -3014,12 +3045,12 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 			fplog(stderr, WARN, "ignore non-seekable output with opos != 0 due to --force\n");
 		else {
 			fplog(stderr, FATAL, "outfile not seekable, but opos !=0 requested!\n");
-			cleanup(); exit(19);
+			cleanup(1); exit(19);
 		}
 	}
 	if (fst->i_chr && op->init_ipos != 0) {
 		fplog(stderr, FATAL, "infile not seekable, but ipos !=0 requested!\n");
-		cleanup(); exit(19);
+		cleanup(1); exit(19);
 	}
 		
 	if (op->dosplice) {
@@ -3031,7 +3062,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 	if (op->noextend || op->extend) {
 		if (output_length(op, fst) == -1) {
 			fplog(stderr, FATAL, "asked to (not) extend output file but can't determine size\n");
-			cleanup(); exit(19);
+			cleanup(1); exit(19);
 		}
 		if (op->extend)
 			op->init_opos += fst->olen;
@@ -3041,7 +3072,7 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 	if (op->init_ipos < 0 || op->init_opos < 0) {
 		fplog(stderr, FATAL, "negative position requested (%skiB)\n", 
 			fmt_kiB(op->init_ipos, !nocol));
-		cleanup(); exit(25);
+		cleanup(1); exit(25);
 	}
 
 #if defined(HAVE_FALLOCATE64) || defined(HAVE_LIBFALLOCATE)
@@ -3049,11 +3080,8 @@ void sanitize_and_prepare(opt_t *op, dpopt_t *dop, fstate_t *fst, dpstate_t *dst
 		do_fallocate(fst->odes, op->oname, op, fst);
 #endif
 
-	if (op->verbose) {
+	if (op->verbose)
 		printinfo(stderr, op);
-		if (logfd)
-			printinfo(logfd, op);
-	}
 
 	if (dop->bsim715 && op->avoidwrite) {
 		fplog(stderr, WARN, "won't avoid writes for -3\n");
@@ -3226,11 +3254,13 @@ int main(int argc, char* argv[])
 	gettimeofday(&currenttime, NULL);
 	printreport(opts, fstate, progress, dpopts);
 	fadvise(1, opts, fstate, progress);
-	err += cleanup();
+	err += cleanup(0);
 	if (int_by == SIGQUIT)
 		++err;
-	if (err && opts->verbose)
+	if (err && !opts->quiet)
 		fplog(stderr, WARN, "There were %i errors! \n", err);
+	if (logfd)
+		fclose(logfd);
 	if (interrupted && int_by != SIGQUIT)
 		return 128+int_by;
 	else
diff --git a/fmt_no.c b/fmt_no.c
index 98f4b57..2af5788 100644
--- a/fmt_no.c
+++ b/fmt_no.c
@@ -24,7 +24,7 @@
 static int mypow(int base, int pwr)
 {
 	int i;
-	float pw = 1;
+	long pw = 1;
 	for (i = 0; i < pwr; ++i)
 		pw *= base;
 	return pw;
@@ -42,6 +42,8 @@ static char fmtbufs[8][64];
  *   we start overwriting buffers. 
  * - The string can't be longer than 64 chars, which should be
  *   enough though to print all possible 64bit ints.
+ * - bold and norm need to be either invisible (boldinvis=1)
+ *   or a single (visible) character or empty/NULL
  */
 char* fmt_int_b(unsigned char pre, unsigned char post, unsigned int scale,
 	       	loff_t no, const char* bold, const char* norm, 
@@ -77,18 +79,18 @@ char* fmt_int_b(unsigned char pre, unsigned char post, unsigned int scale,
 		my_no = (no + scale/2) / scale;
 	for (pos = 0; (pos < pre-isneg || !pre) && (my_no || !pos); ++pos) {
 		unsigned char digit = my_no - base*(my_no/base);
-		if (bold && pos && !(pos % twogroup)) {
+		if (blen && pos && !(pos % twogroup)) {
 			/* insert bold */
 			memcpy(fmtbuf+idx-blen, bold, blen);
 			idx -= blen;
-			if (!boldinvis && --pre <= pos+isneg) {
+			if (!boldinvis && pre && --pre <= pos+isneg) {
 				pos++; break;
 			}
-		} else if (norm && !((pos+group) % twogroup)) {
+		} else if (nlen && !((pos+group) % twogroup)) {
 			/* insert norm */
 			memcpy(fmtbuf+idx-nlen, norm, nlen);
 			idx -= nlen;
-			if (!boldinvis && --pre <= pos+isneg) {
+			if (!boldinvis && pre && --pre <= pos+isneg) {
 				pos++; break;
 			}
 		}
@@ -155,6 +157,12 @@ int main(int argc, char **argv)
 		printf("\n%s\n", fmt_int(0, 1, 1024, l, BOLD, NORM, 1));
 		printf("%s\n",   fmt_int_b(0, 1, 1024, l, BOLD, NORM, 1, 10, 0));
 		printf("0x%s\n\n", fmt_int_b(0, 1, 1024, l, BOLD, NORM, 1, 16, 4));
+		printf("%s\n",   fmt_int_b(0, 0, 1024, l, BOLD, NORM, 1, 10, 3));
+		printf("%s\n\n", fmt_int_b(0, 0, 1024, l, BOLD, NORM, 0, 10, 3));
+		printf("%s\n",   fmt_int_b(0, 0, 1024, l, "", "", 1, 10, 3));
+		printf("%s\n",   fmt_int_b(0, 0, 1024, l, "", "", 0, 10, 3));
+		printf("%s\n",   fmt_int_b(0, 0, 1024, l, NULL, NULL, 1, 10, 3));
+		printf("%s\n",   fmt_int_b(0, 0, 1024, l, NULL, NULL, 0, 10, 3));
 	}
 	return 0;
 }
diff --git a/libddr_crypt.c b/libddr_crypt.c
index b8dc087..5454d07 100644
--- a/libddr_crypt.c
+++ b/libddr_crypt.c
@@ -190,27 +190,13 @@ int crypt_plug_init(void **stat, char* param, int seq, const opt_t *opt)
 	assert(state->sec);
 	state->pad = PAD_ALWAYS;
 	state->saltlen = -1;
-#ifdef HAVE_AESNI
-#ifdef __BIONIC__ //MAY_AESNI
-	have_aesni = detect2("aes", probe_aesni);
-#endif
+#if defined(CC_FLAGS_AES) && (defined(__x86_64__) || defined(__i386__))
 	if (have_aesni) { 
 		state->engine = AESNI_Methods;
 		if (opt->verbose)
 			FPLOG(INFO, "Default to use AESNI crypto extensions\n");
 	} else {
-#endif
-#ifdef HAVE_AES_ARM64
-/* FIXME: Why is this only needed on BIONIC?
- * Does libdl automatically consolidate aliased symbols?
- */
-#ifdef __BIONIC__ //MAY_AES_ARM64
-#ifdef __aarch64__
-	have_arm8crypto = detect2("aes", probe_arm8crypto);
-#else
-	have_arm8crypto = detect2("aes", probe_arm8crypto_32);
-#endif
-#endif
+#elif defined(HAVE_AES_ARM64)
 	if (have_arm8crypto) {
 		state->engine = AES_ARM8_Methods;
 		if (opt->verbose)
diff --git a/rdrand.c b/rdrand.c
index aa3ff8c..35f4525 100644
--- a/rdrand.c
+++ b/rdrand.c
@@ -5,9 +5,10 @@
  * License: GNU GPL v2 or v3
  */
 
+#include "archdep.h"
+
 #ifdef __RDRND__
 #include <immintrin.h>
-#include "archdep.h"
 #define BSWAP32(x) ((x<<24) | ((x<<8)&0x00ff0000) | ((x>>8)&0x0000ff00) | (x>>24))
 
 unsigned int rdrand32()
@@ -40,6 +41,7 @@ void probe_rdrand()
 	_rdrand32_step(&val);
 	_rdrand_res = val;
 }
+#endif	/* RDRND */
 
 #ifdef __AES__
 #include <wmmintrin.h>
@@ -51,12 +53,10 @@ void probe_aesni()
 	_mm_storeu_si128((__m128i*)_aes_probe_res, x);
 }
 #else 
-# warning compile rdrand with -maes
+# warning please compile rdrand with -maes
 #endif
 
 
-#else 
-# warning compile rdrand with -mrdrnd
 #if 0
 unsigned int rdrand32()
 {
@@ -65,6 +65,4 @@ unsigned int rdrand32()
 	return val;
 }
 #endif
-#endif
-
 
diff --git a/test_crypt.sh b/test_crypt.sh
index 768c1de..bea1abc 100755
--- a/test_crypt.sh
+++ b/test_crypt.sh
@@ -187,7 +187,7 @@ for alg in $TESTALGS; do
 		ENG="$ENG aesarm64"
 	fi
 	if test "$HAVE_OPENSSL" = "0"; then ENG=`echo $ENG | sed 's/ openssl//'`; fi
-	if test "$HAVE_RDRNDAES" = "0"; then ENG=`echo $ENG | sed 's/ aesni//'`; fi
+	if test "$HAVE_AES" = "0"; then ENG=`echo $ENG | sed 's/ aesni//'`; fi
 	echo "** Alg $alg engines $ENG **"
 	for engine in $ENG; do
 		enc_dec_compare dd_rescue $alg "" pass=PASSWORD:pbkdf2 $engine
