aboutsummaryrefslogtreecommitdiff
path: root/llvm_mode
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-08-03 13:39:55 +0200
committerGitHub <noreply@github.com>2020-08-03 13:39:55 +0200
commitd5d8d664d0d4b95792aaccd16264f3a3cff48cc8 (patch)
treefa82a04acca16ea3e088b0d7d3aaec4b01ddf8f9 /llvm_mode
parent4a51cb71fb8785325dedac693cdea4648f6e5279 (diff)
parent409e4ae945ab5aeb31b1e3a1497ce5fc65226f07 (diff)
downloadafl++-d5d8d664d0d4b95792aaccd16264f3a3cff48cc8.tar.gz
Merge pull request #477 from AFLplusplus/dev
Push to stable
Diffstat (limited to 'llvm_mode')
-rw-r--r--llvm_mode/GNUmakefile36
-rw-r--r--llvm_mode/LLVMInsTrim.so.cc2
-rw-r--r--llvm_mode/README.instrument_file.md2
-rw-r--r--llvm_mode/README.laf-intel.md4
-rw-r--r--llvm_mode/README.lto.md62
-rw-r--r--llvm_mode/README.md4
-rw-r--r--llvm_mode/README.persistent_mode.md15
-rw-r--r--llvm_mode/afl-clang-fast.c76
-rw-r--r--llvm_mode/afl-llvm-common.cc20
-rw-r--r--llvm_mode/afl-llvm-common.h9
-rw-r--r--llvm_mode/afl-llvm-lto-instrim.so.cc10
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc54
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentlist.so.cc52
-rw-r--r--llvm_mode/afl-llvm-pass.so.cc2
-rw-r--r--llvm_mode/afl-llvm-rt.o.c46
-rw-r--r--llvm_mode/cmplog-instructions-pass.cc3
-rw-r--r--llvm_mode/cmplog-routines-pass.cc3
-rw-r--r--llvm_mode/compare-transform-pass.so.cc9
-rw-r--r--llvm_mode/split-compares-pass.so.cc426
-rw-r--r--llvm_mode/split-switches-pass.so.cc3
20 files changed, 593 insertions, 245 deletions
diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile
index b5d026ef..0813af34 100644
--- a/llvm_mode/GNUmakefile
+++ b/llvm_mode/GNUmakefile
@@ -32,15 +32,16 @@ ifeq "$(shell uname)" "OpenBSD"
LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
ifeq "$(HAS_OPT)" "1"
- $(error llvm_mode needs a complete llvm installation (versions 3.4 up to 11) -> e.g. "pkg_add llvm-7.0.1p9")
+ $(error llvm_mode needs a complete llvm installation (versions 3.4 up to 12) -> e.g. "pkg_add llvm-7.0.1p9")
endif
else
LLVM_CONFIG ?= llvm-config
endif
LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' )
-LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-3]|^1[2-9]' && echo 1 || echo 0 )
+LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-3]|^19' && echo 1 || echo 0 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 )
+LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]' && echo 1 || echo 0 )
LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//')
LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
@@ -53,20 +54,29 @@ ifeq "$(LLVMVER)" ""
endif
ifeq "$(LLVM_UNSUPPORTED)" "1"
- $(warning llvm_mode only supports llvm versions 3.4 up to 11)
+ $(warning llvm_mode only supports llvm versions 3.4 up to 12)
endif
+LLVM_TOO_OLD=1
+
ifeq "$(LLVM_MAJOR)" "9"
$(info [+] llvm_mode detected llvm 9, enabling neverZero implementation)
+ LLVM_TOO_OLD=0
endif
ifeq "$(LLVM_NEW_API)" "1"
$(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14)
LLVM_STDCXX = c++14
+ LLVM_TOO_OLD=0
+endif
+
+ifeq "$(LLVM_TOO_OLD)" "1"
+ $(info [!] llvm_mode detected an old version of llvm, upgrade to at least 9 or preferable 11!)
+ $(shell sleep 1)
endif
-ifeq "$(LLVM_MAJOR)" "11"
- $(info [+] llvm_mode detected llvm 11, enabling afl-clang-lto LTO implementation)
+ifeq "$(LLVM_HAVE_LTO)" "1"
+ $(info [+] llvm_mode detected llvm 11+, enabling afl-clang-lto LTO implementation)
LLVM_LTO = 1
#TEST_MMAP = 1
endif
@@ -182,18 +192,24 @@ ifeq "$(LLVM_LTO)" "1"
ifneq "$(shell readlink $(LLVM_BINDIR)/ld.lld 2>&1)" ""
AFL_REAL_LD = $(LLVM_BINDIR)/ld.lld
else
- $(warn ld.lld not found, can not enable LTO mode)
+ $(warn ld.lld not found, cannot enable LTO mode)
LLVM_LTO = 0
endif
endif
+ else
+ $(warn -flto is not working (LLVMgold.so not found?), cannot enable LTO mode)
+ LLVM_LTO = 0
endif
endif
AFL_CLANG_FUSELD=
-ifneq "$(AFL_CLANG_FLTO)" ""
-ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
- AFL_CLANG_FUSELD=1
-endif
+ifeq "$(LLVM_LTO)" "1"
+ ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+ AFL_CLANG_FUSELD=1
+ else
+ $(warn -fuse-ld is not working, cannot enable LTO mode)
+ LLVM_LTO = 0
+ endif
endif
CFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc
index 75548266..4d8c4719 100644
--- a/llvm_mode/LLVMInsTrim.so.cc
+++ b/llvm_mode/LLVMInsTrim.so.cc
@@ -56,7 +56,6 @@ struct InsTrim : public ModulePass {
protected:
uint32_t function_minimum_size = 1;
- uint32_t debug = 0;
char * skip_nozero = NULL;
private:
@@ -102,7 +101,6 @@ struct InsTrim : public ModulePass {
bool runOnModule(Module &M) override {
- char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
diff --git a/llvm_mode/README.instrument_file.md b/llvm_mode/README.instrument_file.md
index 29c40eec..46e45ba2 100644
--- a/llvm_mode/README.instrument_file.md
+++ b/llvm_mode/README.instrument_file.md
@@ -18,6 +18,8 @@ For this purpose, I have added a "partial instrumentation" support to the LLVM
mode of AFLFuzz that allows you to specify on a source file level which files
should be compiled with or without instrumentation.
+Note: When using PCGUARD mode - and have llvm 12+ - you can use this instead:
+https://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation
## 2) Building the LLVM module
diff --git a/llvm_mode/README.laf-intel.md b/llvm_mode/README.laf-intel.md
index 2fa4bc26..f63ab2bb 100644
--- a/llvm_mode/README.laf-intel.md
+++ b/llvm_mode/README.laf-intel.md
@@ -35,8 +35,8 @@ bit_width may be 64, 32 or 16.
A new experimental feature is splitting floating point comparisons into a
series of sign, exponent and mantissa comparisons followed by splitting each
of them into 8 bit comparisons when necessary.
-It is activated with the `AFL_LLVM_LAF_SPLIT_FLOATS` setting, available only
-when `AFL_LLVM_LAF_SPLIT_COMPARES` is set.
+It is activated with the `AFL_LLVM_LAF_SPLIT_FLOATS` setting.
+Note that setting this automatically activates `AFL_LLVM_LAF_SPLIT_COMPARES`
You can also set `AFL_LLVM_LAF_ALL` and have all of the above enabled :-)
diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md
index 4641fa89..e521ac82 100644
--- a/llvm_mode/README.lto.md
+++ b/llvm_mode/README.lto.md
@@ -2,7 +2,7 @@
## TLDR;
-This version requires a current llvm 11 compiled from the github master.
+This version requires a current llvm 11+ compiled from the github master.
1. Use afl-clang-lto/afl-clang-lto++ because it is faster and gives better
coverage than anything else that is out there in the AFL world
@@ -10,7 +10,7 @@ This version requires a current llvm 11 compiled from the github master.
2. You can use it together with llvm_mode: laf-intel and the instrument file listing
features and can be combined with cmplog/Redqueen
-3. It only works with llvm 11 (current github master state)
+3. It only works with llvm 11+
4. AUTODICTIONARY feature! see below
@@ -61,9 +61,9 @@ AUTODICTIONARY: 11 strings found
[+] Instrumented 12071 locations with no collisions (on average 1046 collisions would be in afl-gcc/afl-clang-fast) (non-hardened mode).
```
-## Getting llvm 11
+## Getting llvm 11+
-### Installing llvm 11 from the llvm repository
+### Installing llvm from the llvm repository (version 11)
Installing the llvm snapshot builds is easy and mostly painless:
@@ -83,7 +83,7 @@ apt-get install -y clang-11 clang-tools-11 libc++1-11 libc++-11-dev \
libomp5-11 lld-11 lldb-11 llvm-11 llvm-11-dev llvm-11-runtime llvm-11-tools
```
-### Building llvm 11 yourself
+### Building llvm yourself (version 12)
Building llvm from github takes quite some long time and is not painless:
```
@@ -125,10 +125,9 @@ NOTE: some targets also need to set the linker, try both `afl-clang-lto` and
## AUTODICTIONARY feature
-Setting `AFL_LLVM_LTO_AUTODICTIONARY` will generate a dictionary in the
-target binary based on string compare and memory compare functions.
-afl-fuzz will automatically get these transmitted when starting to fuzz.
-This improves coverage on a lot of targets.
+While compiling, automatically a dictionary based on string comparisons is
+generated put into the target binary. This dictionary is transfered to afl-fuzz
+on start. This improves coverage statistically by 5-10% :)
## Fixed memory map
@@ -141,12 +140,20 @@ to be dynamic - the original afl way, which is slower).
AFL_LLVM_MAP_DYNAMIC can be set so the shared memory address is dynamic (which
is safer but also slower).
+## Document edge IDs
+
+Setting `export AFL_LLVM_DOCUMENT_IDS=file` will document to a file which edge
+ID was given to which function. This helps to identify functions with variable
+bytes or which functions were touched by an input.
+
## Solving difficult targets
Some targets are difficult because the configure script does unusual stuff that
is unexpected for afl. See the next chapter `Potential issues` how to solve
these.
+### Example: ffmpeg
+
An example of a hard to solve target is ffmpeg. Here is how to successfully
instrument it:
@@ -156,7 +163,7 @@ instrument it:
when compiling, so we have to trick configure:
```
-./configure --enable-lto --disable-shared
+./configure --enable-lto --disable-shared --disable-inline-asm
```
3. Now the configuration is done - and we edit the settings in `./ffbuild/config.mak`
@@ -186,6 +193,31 @@ instrument it:
4. Then type make, wait for a long time and you are done :)
+### Example: WebKit jsc
+
+Building jsc is difficult as the build script has bugs.
+
+1. checkout Webkit:
+```
+svn checkout https://svn.webkit.org/repository/webkit/trunk WebKit
+cd WebKit
+```
+
+2. Fix the build environment:
+```
+mkdir -p WebKitBuild/Release
+cd WebKitBuild/Release
+ln -s ../../../../../usr/bin/llvm-ar-12 llvm-ar-12
+ln -s ../../../../../usr/bin/llvm-ranlib-12 llvm-ranlib-12
+cd ../..
+```
+
+3. Build :)
+
+```
+Tools/Scripts/build-jsc --jsc-only --cli --cmakeargs="-DCMAKE_AR='llvm-ar-12' -DCMAKE_RANLIB='llvm-ranlib-12' -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_CC_FLAGS='-O3 -lrt' -DCMAKE_CXX_FLAGS='-O3 -lrt' -DIMPORTED_LOCATION='/lib/x86_64-linux-gnu/' -DCMAKE_CC=afl-clang-lto -DCMAKE_CXX=afl-clang-lto++ -DENABLE_STATIC_JSC=ON"
+```
+
## Potential issues
### compiling libraries fails
@@ -220,17 +252,17 @@ AS=llvm-as ...
afl-clang-lto is still work in progress.
Known issues:
- * Anything that llvm 11 cannot compile, afl-clang-lto can not compile either - obviously
+ * Anything that llvm 11+ cannot compile, afl-clang-lto can not compile either - obviously
* Anything that does not compile with LTO, afl-clang-lto can not compile either - obviously
-Hence if building a target with afl-clang-lto fails try to build it with llvm11
-and LTO enabled (`CC=clang-11` `CXX=clang++-11` `CFLAGS=-flto=full` and
+Hence if building a target with afl-clang-lto fails try to build it with llvm12
+and LTO enabled (`CC=clang-12` `CXX=clang++-12` `CFLAGS=-flto=full` and
`CXXFLAGS=-flto=full`).
If this succeeeds then there is an issue with afl-clang-lto. Please report at
[https://github.com/AFLplusplus/AFLplusplus/issues/226](https://github.com/AFLplusplus/AFLplusplus/issues/226)
-Even some targets where clang-11 fails can be build if the fail is just in
+Even some targets where clang-12 fails can be build if the fail is just in
`./configure`, see `Solving difficult targets` above.
### Target crashes immediately
@@ -270,7 +302,7 @@ Still more problems came up though as this only works without bugs from
llvm 9 onwards, and with high optimization the link optimization ruins
the instrumented control flow graph.
-This is all now fixed with llvm 11. The llvm's own linker is now able to
+This is all now fixed with llvm 11+. The llvm's own linker is now able to
load passes and this bypasses all problems we had.
Happy end :)
diff --git a/llvm_mode/README.md b/llvm_mode/README.md
index e2e22751..22088dfd 100644
--- a/llvm_mode/README.md
+++ b/llvm_mode/README.md
@@ -6,7 +6,7 @@
## 1) Introduction
-! llvm_mode works with llvm versions 3.4 up to 11 !
+! llvm_mode works with llvm versions 3.4 up to 12 !
The code in this directory allows you to instrument programs for AFL using
true compiler-level instrumentation, instead of the more crude
@@ -183,4 +183,4 @@ AFL_LLVM_INSTRUMENT=PCGUARD make
```
Note that this us currently the default, as it is the best mode.
-If you have llvm 11 and compiled afl-clang-lto - this is the only better mode.
+If you have llvm 11+ and compiled afl-clang-lto - this is the only better mode.
diff --git a/llvm_mode/README.persistent_mode.md b/llvm_mode/README.persistent_mode.md
index 83cc7f4d..4f0bcb2e 100644
--- a/llvm_mode/README.persistent_mode.md
+++ b/llvm_mode/README.persistent_mode.md
@@ -52,6 +52,21 @@ afl-clang-fast -o fuzz_target fuzz_target.c -lwhat_you_need_for_your_target
And that is it!
The speed increase is usually x10 to x20.
+If you want to be able to compile the target without afl-clang-fast/lto then
+add this just after the includes:
+
+```
+#ifndef __AFL_FUZZ_TESTCASE_LEN
+ ssize_t fuzz_len;
+ #define __AFL_FUZZ_TESTCASE_LEN fuzz_len
+ unsigned char fuzz_buf[1024000];
+ #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
+ #define __AFL_FUZZ_INIT() void sync(void);
+ #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ?
+ #define __AFL_INIT() sync()
+#endif
+```
+
## 3) deferred initialization
AFL tries to optimize performance by executing the targeted binary just once,
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index f1b03682..738433ac 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -162,6 +162,7 @@ static void find_obj(u8 *argv0) {
static void edit_params(u32 argc, char **argv, char **envp) {
u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0;
+ u8 have_pic = 0;
u8 *name;
cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
@@ -268,7 +269,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES")) {
+ if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
+ getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) {
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
@@ -311,12 +313,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", AFL_REAL_LD);
cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
- if (instrument_mode == INSTRUMENT_CFG)
- cc_params[cc_par_cnt++] =
- alloc_printf("-Wl,-mllvm=-load=%s/afl-llvm-lto-instrim.so", obj_path);
- else
- cc_params[cc_par_cnt++] = alloc_printf(
- "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path);
+ /*
+ The current LTO instrim mode is not good, so we disable it
+ if (instrument_mode == INSTRUMENT_CFG)
+ cc_params[cc_par_cnt++] =
+ alloc_printf("-Wl,-mllvm=-load=%s/afl-llvm-lto-instrim.so",
+ obj_path); else
+ */
+ cc_params[cc_par_cnt++] = alloc_printf(
+ "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path);
cc_params[cc_par_cnt++] = lto_flag;
} else {
@@ -359,6 +364,19 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
+ u32 idx;
+ if (lto_mode && argc > 1) {
+
+ for (idx = 1; idx < argc; idx++) {
+
+ if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
+
+ }
+
+ if (!have_pic) cc_params[cc_par_cnt++] = "-fPIC";
+
+ }
+
/* Detect stray -v calls from ./configure scripts. */
while (--argc) {
@@ -379,6 +397,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined"))
continue;
+ if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
+
cc_params[cc_par_cnt++] = cur;
}
@@ -500,13 +520,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
"int __afl_sharedmem_fuzzing = 1;"
"extern unsigned int *__afl_fuzz_len;"
"extern unsigned char *__afl_fuzz_ptr;"
- "unsigned char *__afl_fuzz_alt_ptr;";
+ "unsigned char __afl_fuzz_alt[1024000];"
+ "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;";
cc_params[cc_par_cnt++] =
"-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
- "(__afl_fuzz_alt_ptr = (unsigned char *) malloc(1 * 1024 * 1024)))";
+ "__afl_fuzz_alt_ptr)";
cc_params[cc_par_cnt++] =
- "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : read(0, "
- "__afl_fuzz_alt_ptr, 1 * 1024 * 1024))";
+ "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : "
+ "(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1024000)) == 0xffffffff "
+ "? 0 : *__afl_fuzz_len)";
cc_params[cc_par_cnt++] =
"-D__AFL_LOOP(_A)="
@@ -617,6 +639,10 @@ int main(int argc, char **argv, char **envp) {
}
+ if ((getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) &&
+ getenv("AFL_DONT_OPTIMIZE"))
+ FATAL("AFL_LLVM_INSTRUMENT_FILE and AFL_DONT_OPTIMIZE cannot be combined");
+
if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") ||
getenv("INSTRIM_LIB")) {
@@ -660,7 +686,7 @@ int main(int argc, char **argv, char **envp) {
}
if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 ||
- strncasecmp(ptr, "pcguard", strlen("pcgard")) == 0) {
+ strncasecmp(ptr, "pcguard", strlen("pcguard")) == 0) {
if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD)
instrument_mode = INSTRUMENT_PCGUARD;
@@ -763,9 +789,19 @@ int main(int argc, char **argv, char **envp) {
#if LLVM_VERSION_MAJOR <= 6
instrument_mode = INSTRUMENT_AFL;
#else
- if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST"))
+ if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) {
+
instrument_mode = INSTRUMENT_AFL;
- else
+ WARNF(
+ "switching to classic instrumentation because "
+ "AFL_LLVM_INSTRUMENT_FILE does not work with PCGUARD. Use "
+ "-fsanitize-coverage-allowlist=allowlist.txt if you want to use "
+ "PCGUARD. Requires llvm 12+. See "
+ "https://clang.llvm.org/docs/"
+ "SanitizerCoverage.html#partially-disabling-instrumentation");
+
+ } else
+
instrument_mode = INSTRUMENT_PCGUARD;
#endif
@@ -813,9 +849,13 @@ int main(int argc, char **argv, char **envp) {
if (instrument_mode == INSTRUMENT_PCGUARD &&
(getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")))
- WARNF(
+ FATAL(
"Instrumentation type PCGUARD does not support "
- "AFL_LLVM_INSTRUMENT_FILE!");
+ "AFL_LLVM_INSTRUMENT_FILE! Use "
+ "-fsanitize-coverage-allowlist=allowlist.txt instead (requires llvm "
+ "12+), see "
+ "https://clang.llvm.org/docs/"
+ "SanitizerCoverage.html#partially-disabling-instrumentation");
if (argc < 2 || strcmp(argv[1], "-h") == 0) {
@@ -871,6 +911,8 @@ int main(int argc, char **argv, char **envp) {
"AFL_NO_BUILTIN: compile for use with libtokencap.so\n"
"AFL_PATH: path to instrumenting pass and runtime "
"(afl-llvm-rt.*o)\n"
+ "AFL_LLVM_DOCUMENT_IDS: document edge IDs given to which function (LTO "
+ "only)\n"
"AFL_QUIET: suppress verbose output\n"
"AFL_USE_ASAN: activate address sanitizer\n"
"AFL_USE_CFISAN: activate control flow sanitizer\n"
@@ -939,7 +981,7 @@ int main(int argc, char **argv, char **envp) {
u32 map_size = atoi(ptr2);
if (map_size != MAP_SIZE)
- FATAL("AFL_MAP_SIZE is not supported by afl-clang-fast");
+ WARNF("AFL_MAP_SIZE is not supported by afl-clang-fast");
}
diff --git a/llvm_mode/afl-llvm-common.cc b/llvm_mode/afl-llvm-common.cc
index 47b49358..9a884ded 100644
--- a/llvm_mode/afl-llvm-common.cc
+++ b/llvm_mode/afl-llvm-common.cc
@@ -14,6 +14,8 @@
#include <fstream>
#include <llvm/Support/raw_ostream.h>
+
+#define IS_EXTERN extern
#include "afl-llvm-common.h"
using namespace llvm;
@@ -88,6 +90,7 @@ void initInstrumentList() {
char *instrumentListFilename = getenv("AFL_LLVM_INSTRUMENT_FILE");
if (!instrumentListFilename)
instrumentListFilename = getenv("AFL_LLVM_WHITELIST");
+
if (instrumentListFilename) {
std::string line;
@@ -105,6 +108,10 @@ void initInstrumentList() {
}
+ if (debug)
+ SAYF(cMGN "[D] " cRST "loaded instrument list with %zu entries\n",
+ myInstrumentList.size());
+
}
bool isInInstrumentList(llvm::Function *F) {
@@ -145,8 +152,6 @@ bool isInInstrumentList(llvm::Function *F) {
}
- (void)instLine;
-
/* Continue only if we know where we actually are */
if (!instFilename.str().empty()) {
@@ -164,6 +169,10 @@ bool isInInstrumentList(llvm::Function *F) {
if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
0) {
+ if (debug)
+ SAYF(cMGN "[D] " cRST
+ "Function %s is in the list (%s), instrumenting ... \n",
+ F->getName().str().c_str(), instFilename.str().c_str());
return true;
}
@@ -219,12 +228,15 @@ bool isInInstrumentList(llvm::Function *F) {
// we could not find out the location. in this case we say it is not
// in the the instrument file list
-
+ if (!be_quiet)
+ WARNF(
+ "No debug information found for function %s, will not be "
+ "instrumented (recompile with -g -O[1-3]).",
+ F->getName().str().c_str());
return false;
}
- //
return false;
}
diff --git a/llvm_mode/afl-llvm-common.h b/llvm_mode/afl-llvm-common.h
index 38e0c830..5b96be43 100644
--- a/llvm_mode/afl-llvm-common.h
+++ b/llvm_mode/afl-llvm-common.h
@@ -38,5 +38,14 @@ void initInstrumentList();
bool isInInstrumentList(llvm::Function *F);
unsigned long long int calculateCollisions(uint32_t edges);
+#ifndef IS_EXTERN
+ #define IS_EXTERN
+#endif
+
+IS_EXTERN int debug;
+IS_EXTERN int be_quiet;
+
+#undef IS_EXTERN
+
#endif
diff --git a/llvm_mode/afl-llvm-lto-instrim.so.cc b/llvm_mode/afl-llvm-lto-instrim.so.cc
index ca2b5886..98e9ff9a 100644
--- a/llvm_mode/afl-llvm-lto-instrim.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrim.so.cc
@@ -73,8 +73,8 @@ struct InsTrimLTO : public ModulePass {
protected:
uint32_t function_minimum_size = 1;
char * skip_nozero = NULL;
- int afl_global_id = 1, debug = 0, autodictionary = 0;
- uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0;
+ int afl_global_id = 1, autodictionary = 1;
+ uint32_t inst_blocks = 0, inst_funcs = 0;
uint64_t map_addr = 0x10000;
public:
@@ -127,10 +127,6 @@ struct InsTrimLTO : public ModulePass {
/* Process environment variables */
- if (getenv("AFL_LLVM_AUTODICTIONARY") ||
- getenv("AFL_LLVM_LTO_AUTODICTIONARY"))
- autodictionary = 1;
-
if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0;
if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) {
@@ -705,7 +701,7 @@ struct InsTrimLTO : public ModulePass {
Value *Incr = IRB.CreateAdd(Counter, One);
- if (skip_nozero) {
+ if (skip_nozero == NULL) {
auto cf = IRB.CreateICmpEQ(Incr, Zero);
auto carry = IRB.CreateZExt(cf, Int8Ty);
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index af2db3ff..5686eb56 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -86,9 +86,9 @@ class AFLLTOPass : public ModulePass {
bool runOnModule(Module &M) override;
protected:
- int afl_global_id = 1, debug = 0, autodictionary = 0;
+ int afl_global_id = 1, autodictionary = 1;
uint32_t function_minimum_size = 1;
- uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0, total_instr = 0;
+ uint32_t inst_blocks = 0, inst_funcs = 0, total_instr = 0;
uint64_t map_addr = 0x10000;
char * skip_nozero = NULL;
@@ -103,6 +103,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
std::vector<CallInst *> calls;
DenseMap<Value *, std::string *> valueMap;
char * ptr;
+ FILE * documentFile = NULL;
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
@@ -120,15 +121,16 @@ bool AFLLTOPass::runOnModule(Module &M) {
be_quiet = 1;
- if (getenv("AFL_LLVM_AUTODICTIONARY") ||
- getenv("AFL_LLVM_LTO_AUTODICTIONARY"))
- autodictionary = 1;
+ if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
+
+ if ((documentFile = fopen(ptr, "a")) == NULL)
+ WARNF("Cannot access document file %s", ptr);
+
+ }
if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0;
- if (getenv("AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK") ||
- getenv("AFL_LLVM_SKIPSINGLEBLOCK"))
- function_minimum_size = 2;
+ if (getenv("AFL_LLVM_SKIPSINGLEBLOCK")) function_minimum_size = 2;
if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) {
@@ -204,7 +206,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
if (debug)
fprintf(stderr,
- "DEBUG: Function %s is not the instrument file listed\n",
+ "DEBUG: Function %s is not in a source file that was specified "
+ "in the instrument file list\n",
F.getName().str().c_str());
continue;
@@ -536,6 +539,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
uint32_t succ = 0;
+ if (F.size() == 1) InsBlocks.push_back(&BB);
+
for (succ_iterator SI = succ_begin(&BB), SE = succ_end(&BB); SI != SE;
++SI)
if ((*SI)->size() > 0) succ++;
@@ -554,9 +559,12 @@ bool AFLLTOPass::runOnModule(Module &M) {
do {
--i;
+ BasicBlock * newBB;
BasicBlock * origBB = &(*InsBlocks[i]);
std::vector<BasicBlock *> Successors;
Instruction * TI = origBB->getTerminator();
+ uint32_t fs = origBB->getParent()->size();
+ uint32_t countto;
for (succ_iterator SI = succ_begin(origBB), SE = succ_end(origBB);
SI != SE; ++SI) {
@@ -566,15 +574,25 @@ bool AFLLTOPass::runOnModule(Module &M) {
}
- if (TI == NULL || TI->getNumSuccessors() < 2) continue;
+ if (fs == 1) {
+
+ newBB = origBB;
+ countto = 1;
+
+ } else {
+
+ if (TI == NULL || TI->getNumSuccessors() < 2) continue;
+ countto = Successors.size();
+
+ }
// if (Successors.size() != TI->getNumSuccessors())
// FATAL("Different successor numbers %lu <-> %u\n", Successors.size(),
// TI->getNumSuccessors());
- for (uint32_t j = 0; j < Successors.size(); j++) {
+ for (uint32_t j = 0; j < countto; j++) {
- BasicBlock *newBB = llvm::SplitEdge(origBB, Successors[j]);
+ if (fs != 1) newBB = llvm::SplitEdge(origBB, Successors[j]);
if (!newBB) {
@@ -583,6 +601,13 @@ bool AFLLTOPass::runOnModule(Module &M) {
}
+ if (documentFile) {
+
+ fprintf(documentFile, "%s %u\n", F.getName().str().c_str(),
+ afl_global_id);
+
+ }
+
BasicBlock::iterator IP = newBB->getFirstInsertionPt();
IRBuilder<> IRB(&(*IP));
@@ -615,7 +640,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
Value *Incr = IRB.CreateAdd(Counter, One);
- if (skip_nozero) {
+ if (skip_nozero == NULL) {
auto cf = IRB.CreateICmpEQ(Incr, Zero);
auto carry = IRB.CreateZExt(cf, Int8Ty);
@@ -638,6 +663,9 @@ bool AFLLTOPass::runOnModule(Module &M) {
}
+ if (documentFile) fclose(documentFile);
+ documentFile = NULL;
+
// save highest location ID to global variable
// do this after each function to fail faster
if (!be_quiet && afl_global_id > MAP_SIZE &&
diff --git a/llvm_mode/afl-llvm-lto-instrumentlist.so.cc b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc
index 6e6199e9..ab7c0c58 100644
--- a/llvm_mode/afl-llvm-lto-instrumentlist.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentlist.so.cc
@@ -104,7 +104,6 @@ class AFLcheckIfInstrument : public ModulePass {
protected:
std::list<std::string> myInstrumentList;
- int debug = 0;
};
@@ -116,7 +115,6 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
/* Show a banner */
- char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
@@ -164,32 +162,41 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
}
+ if (instFilename.str().empty()) {
+
+ if (!be_quiet)
+ WARNF(
+ "Function %s has no source file name information and will "
+ "not be instrumented.",
+ F.getName().str().c_str());
+ continue;
+
+ }
+
}
- (void)instLine;
+ //(void)instLine;
+ fprintf(stderr, "xxx %s %s\n", F.getName().str().c_str(),
+ instFilename.str().c_str());
if (debug)
SAYF(cMGN "[D] " cRST "function %s is in file %s\n",
F.getName().str().c_str(), instFilename.str().c_str());
- /* Continue only if we know where we actually are */
- if (!instFilename.str().empty()) {
- for (std::list<std::string>::iterator it = myInstrumentList.begin();
- it != myInstrumentList.end(); ++it) {
+ for (std::list<std::string>::iterator it = myInstrumentList.begin();
+ it != myInstrumentList.end(); ++it) {
- /* We don't check for filename equality here because
- * filenames might actually be full paths. Instead we
- * check that the actual filename ends in the filename
- * specified in the list. */
- if (instFilename.str().length() >= it->length()) {
+ /* We don't check for filename equality here because
+ * filenames might actually be full paths. Instead we
+ * check that the actual filename ends in the filename
+ * specified in the list. */
+ if (instFilename.str().length() >= it->length()) {
- if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
- 0) {
+ if (fnmatch(("*" + *it).c_str(), instFilename.str().c_str(), 0) ==
+ 0) {
- instrumentFunction = true;
- break;
-
- }
+ instrumentFunction = true;
+ break;
}
@@ -197,6 +204,15 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
}
+ } else {
+
+ if (!be_quiet)
+ WARNF(
+ "No debug information found for function %s, recompile with -g "
+ "-O[1-3]",
+ F.getName().str().c_str());
+ continue;
+
}
/* Either we couldn't figure out our location or the location is
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
index 90cf3eb4..618abe48 100644
--- a/llvm_mode/afl-llvm-pass.so.cc
+++ b/llvm_mode/afl-llvm-pass.so.cc
@@ -82,7 +82,6 @@ class AFLCoverage : public ModulePass {
protected:
uint32_t ngram_size = 0;
- uint32_t debug = 0;
uint32_t map_size = MAP_SIZE;
uint32_t function_minimum_size = 1;
char * ctx_str = NULL, *skip_nozero = NULL;
@@ -139,7 +138,6 @@ bool AFLCoverage::runOnModule(Module &M) {
/* Show a banner */
- char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if (getenv("AFL_DEBUG")) debug = 1;
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
index f81d13ee..88abcbe0 100644
--- a/llvm_mode/afl-llvm-rt.o.c
+++ b/llvm_mode/afl-llvm-rt.o.c
@@ -53,7 +53,11 @@
#define CONST_PRIO 5
#ifndef MAP_FIXED_NOREPLACE
- #define MAP_FIXED_NOREPLACE MAP_FIXED
+ #ifdef MAP_EXCL
+ #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED
+ #else
+ #define MAP_FIXED_NOREPLACE MAP_FIXED
+ #endif
#endif
#include <sys/mman.h>
@@ -510,12 +514,19 @@ static void __afl_start_snapshots(void) {
if (!child_pid) {
+ //(void)nice(-20); // does not seem to improve
+
signal(SIGCHLD, old_sigchld_handler);
close(FORKSRV_FD);
close(FORKSRV_FD + 1);
- if (!afl_snapshot_do()) { raise(SIGSTOP); }
+ if (!afl_snapshot_take(AFL_SNAPSHOT_MMAP | AFL_SNAPSHOT_FDS |
+ AFL_SNAPSHOT_REGS | AFL_SNAPSHOT_EXIT)) {
+
+ raise(SIGSTOP);
+
+ }
__afl_area_ptr[0] = 1;
memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
@@ -713,6 +724,8 @@ static void __afl_start_forkserver(void) {
if (!child_pid) {
+ //(void)nice(-20);
+
signal(SIGCHLD, old_sigchld_handler);
close(FORKSRV_FD);
@@ -846,6 +859,35 @@ __attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
+ // For stability analysis, if you want to know to which function unstable
+ // edge IDs belong to - uncomment, recompile+install llvm_mode, recompile
+ // the target. libunwind and libbacktrace are better solutions.
+ // Set AFL_DEBUG_CHILD_OUTPUT=1 and run afl-fuzz with 2>file to capture
+ // the backtrace output
+ /*
+ uint32_t unstable[] = { ... unstable edge IDs };
+ uint32_t idx;
+ char bt[1024];
+ for (idx = 0; i < sizeof(unstable)/sizeof(uint32_t); i++) {
+
+ if (unstable[idx] == __afl_area_ptr[*guard]) {
+
+ int bt_size = backtrace(bt, 256);
+ if (bt_size > 0) {
+
+ char **bt_syms = backtrace_symbols(bt, bt_size);
+ if (bt_syms)
+ fprintf(stderr, "DEBUG: edge=%u caller=%s\n", unstable[idx],
+ bt_syms[0]);
+
+ }
+
+ }
+
+ }
+
+ */
+
__afl_area_ptr[*guard]++;
}
diff --git a/llvm_mode/cmplog-instructions-pass.cc b/llvm_mode/cmplog-instructions-pass.cc
index f929361a..7c48d906 100644
--- a/llvm_mode/cmplog-instructions-pass.cc
+++ b/llvm_mode/cmplog-instructions-pass.cc
@@ -76,9 +76,6 @@ class CmpLogInstructions : public ModulePass {
}
- protected:
- int be_quiet = 0;
-
private:
bool hookInstrs(Module &M);
diff --git a/llvm_mode/cmplog-routines-pass.cc b/llvm_mode/cmplog-routines-pass.cc
index 318193a4..a0f8f64f 100644
--- a/llvm_mode/cmplog-routines-pass.cc
+++ b/llvm_mode/cmplog-routines-pass.cc
@@ -76,9 +76,6 @@ class CmpLogRoutines : public ModulePass {
}
- protected:
- int be_quiet = 0;
-
private:
bool hookRtns(Module &M);
diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc
index 2d1ab1cc..bed3597a 100644
--- a/llvm_mode/compare-transform-pass.so.cc
+++ b/llvm_mode/compare-transform-pass.so.cc
@@ -75,9 +75,6 @@ class CompareTransform : public ModulePass {
}
- protected:
- int be_quiet = 0;
-
private:
bool transformCmps(Module &M, const bool processStrcmp,
const bool processMemcmp, const bool processStrncmp,
@@ -358,7 +355,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
Value * VarStr;
bool HasStr1 = getConstantStringInfo(Str1P, Str1);
bool HasStr2 = getConstantStringInfo(Str2P, Str2);
- uint64_t constStrLen, constSizedLen, unrollLen;
+ uint64_t constStrLen, unrollLen, constSizedLen = 0;
bool isMemcmp =
!callInst->getCalledFunction()->getName().compare(StringRef("memcmp"));
bool isSizedcmp = isMemcmp ||
@@ -474,8 +471,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
if (cur_lenchk_bb) {
IRBuilder<> cur_lenchk_IRB(&*(cur_lenchk_bb->getFirstInsertionPt()));
- Value * icmp = cur_lenchk_IRB.CreateICmpEQ(sizedValue,
- ConstantInt::get(Int64Ty, i));
+ Value * icmp = cur_lenchk_IRB.CreateICmpEQ(
+ sizedValue, ConstantInt::get(sizedValue->getType(), i));
cur_lenchk_IRB.CreateCondBr(icmp, end_bb, cur_cmp_bb);
cur_lenchk_bb->getTerminator()->eraseFromParent();
diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc
index 651fa5b4..3630bd8c 100644
--- a/llvm_mode/split-compares-pass.so.cc
+++ b/llvm_mode/split-compares-pass.so.cc
@@ -71,15 +71,13 @@ class SplitComparesTransform : public ModulePass {
}
- protected:
- int be_quiet = 0;
-
private:
int enableFPSplit;
size_t splitIntCompares(Module &M, unsigned bitw);
size_t splitFPCompares(Module &M);
bool simplifyCompares(Module &M);
+ bool simplifyFPCompares(Module &M);
bool simplifyIntSignedness(Module &M);
size_t nextPowerOfTwo(size_t in);
@@ -89,12 +87,11 @@ class SplitComparesTransform : public ModulePass {
char SplitComparesTransform::ID = 0;
-/* This function splits ICMP instructions with xGE or xLE predicates into two
- * ICMP instructions with predicate xGT or xLT and EQ */
-bool SplitComparesTransform::simplifyCompares(Module &M) {
+/* This function splits FCMP instructions with xGE or xLE predicates into two
+ * FCMP instructions with predicate xGT or xLT and EQ */
+bool SplitComparesTransform::simplifyFPCompares(Module &M) {
LLVMContext & C = M.getContext();
- std::vector<Instruction *> icomps;
std::vector<Instruction *> fcomps;
IntegerType * Int1Ty = IntegerType::getInt1Ty(C);
@@ -112,24 +109,6 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
- if (selectcmpInst->getPredicate() == CmpInst::ICMP_UGE ||
- selectcmpInst->getPredicate() == CmpInst::ICMP_SGE ||
- selectcmpInst->getPredicate() == CmpInst::ICMP_ULE ||
- selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) {
-
- auto op0 = selectcmpInst->getOperand(0);
- auto op1 = selectcmpInst->getOperand(1);
-
- IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
- IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
-
- /* this is probably not needed but we do it anyway */
- if (!intTyOp0 || !intTyOp1) { continue; }
-
- icomps.push_back(selectcmpInst);
-
- }
-
if (enableFPSplit &&
(selectcmpInst->getPredicate() == CmpInst::FCMP_OGE ||
selectcmpInst->getPredicate() == CmpInst::FCMP_UGE ||
@@ -159,105 +138,159 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
}
- if (!icomps.size() && !fcomps.size()) { return false; }
+ if (!fcomps.size()) { return false; }
- for (auto &IcmpInst : icomps) {
+ /* transform for floating point */
+ for (auto &FcmpInst : fcomps) {
- BasicBlock *bb = IcmpInst->getParent();
+ BasicBlock *bb = FcmpInst->getParent();
- auto op0 = IcmpInst->getOperand(0);
- auto op1 = IcmpInst->getOperand(1);
+ auto op0 = FcmpInst->getOperand(0);
+ auto op1 = FcmpInst->getOperand(1);
/* find out what the new predicate is going to be */
- auto pred = dyn_cast<CmpInst>(IcmpInst)->getPredicate();
+ auto pred = dyn_cast<CmpInst>(FcmpInst)->getPredicate();
CmpInst::Predicate new_pred;
switch (pred) {
- case CmpInst::ICMP_UGE:
- new_pred = CmpInst::ICMP_UGT;
+ case CmpInst::FCMP_UGE:
+ new_pred = CmpInst::FCMP_UGT;
break;
- case CmpInst::ICMP_SGE:
- new_pred = CmpInst::ICMP_SGT;
+ case CmpInst::FCMP_OGE:
+ new_pred = CmpInst::FCMP_OGT;
break;
- case CmpInst::ICMP_ULE:
- new_pred = CmpInst::ICMP_ULT;
+ case CmpInst::FCMP_ULE:
+ new_pred = CmpInst::FCMP_ULT;
break;
- case CmpInst::ICMP_SLE:
- new_pred = CmpInst::ICMP_SLT;
+ case CmpInst::FCMP_OLE:
+ new_pred = CmpInst::FCMP_OLT;
break;
default: // keep the compiler happy
continue;
}
- /* split before the icmp instruction */
- BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(IcmpInst));
+ /* split before the fcmp instruction */
+ BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst));
/* the old bb now contains a unconditional jump to the new one (end_bb)
* we need to delete it later */
- /* create the ICMP instruction with new_pred and add it to the old basic
- * block bb it is now at the position where the old IcmpInst was */
- Instruction *icmp_np;
- icmp_np = CmpInst::Create(Instruction::ICmp, new_pred, op0, op1);
+ /* create the FCMP instruction with new_pred and add it to the old basic
+ * block bb it is now at the position where the old FcmpInst was */
+ Instruction *fcmp_np;
+ fcmp_np = CmpInst::Create(Instruction::FCmp, new_pred, op0, op1);
bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()),
- icmp_np);
+ fcmp_np);
- /* create a new basic block which holds the new EQ icmp */
- Instruction *icmp_eq;
+ /* create a new basic block which holds the new EQ fcmp */
+ Instruction *fcmp_eq;
/* insert middle_bb before end_bb */
BasicBlock *middle_bb =
BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
- icmp_eq = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, op0, op1);
- middle_bb->getInstList().push_back(icmp_eq);
+ fcmp_eq = CmpInst::Create(Instruction::FCmp, CmpInst::FCMP_OEQ, op0, op1);
+ middle_bb->getInstList().push_back(fcmp_eq);
/* add an unconditional branch to the end of middle_bb with destination
* end_bb */
BranchInst::Create(end_bb, middle_bb);
/* replace the uncond branch with a conditional one, which depends on the
- * new_pred icmp. True goes to end, false to the middle (injected) bb */
+ * new_pred fcmp. True goes to end, false to the middle (injected) bb */
auto term = bb->getTerminator();
- BranchInst::Create(end_bb, middle_bb, icmp_np, bb);
+ BranchInst::Create(end_bb, middle_bb, fcmp_np, bb);
term->eraseFromParent();
- /* replace the old IcmpInst (which is the first inst in end_bb) with a PHI
+ /* replace the old FcmpInst (which is the first inst in end_bb) with a PHI
* inst to wire up the loose ends */
PHINode *PN = PHINode::Create(Int1Ty, 2, "");
- /* the first result depends on the outcome of icmp_eq */
- PN->addIncoming(icmp_eq, middle_bb);
- /* if the source was the original bb we know that the icmp_np yielded true
+ /* the first result depends on the outcome of fcmp_eq */
+ PN->addIncoming(fcmp_eq, middle_bb);
+ /* if the source was the original bb we know that the fcmp_np yielded true
* hence we can hardcode this value */
PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb);
- /* replace the old IcmpInst with our new and shiny PHI inst */
- BasicBlock::iterator ii(IcmpInst);
- ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN);
+ /* replace the old FcmpInst with our new and shiny PHI inst */
+ BasicBlock::iterator ii(FcmpInst);
+ ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN);
}
- /* now for floating point */
- for (auto &FcmpInst : fcomps) {
+ return true;
- BasicBlock *bb = FcmpInst->getParent();
+}
- auto op0 = FcmpInst->getOperand(0);
- auto op1 = FcmpInst->getOperand(1);
+/* This function splits ICMP instructions with xGE or xLE predicates into two
+ * ICMP instructions with predicate xGT or xLT and EQ */
+bool SplitComparesTransform::simplifyCompares(Module &M) {
+
+ LLVMContext & C = M.getContext();
+ std::vector<Instruction *> icomps;
+ IntegerType * Int1Ty = IntegerType::getInt1Ty(C);
+
+ /* iterate over all functions, bbs and instruction and add
+ * all integer comparisons with >= and <= predicates to the icomps vector */
+ for (auto &F : M) {
+
+ if (!isInInstrumentList(&F)) continue;
+
+ for (auto &BB : F) {
+
+ for (auto &IN : BB) {
+
+ CmpInst *selectcmpInst = nullptr;
+
+ if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
+
+ if (selectcmpInst->getPredicate() == CmpInst::ICMP_UGE ||
+ selectcmpInst->getPredicate() == CmpInst::ICMP_SGE ||
+ selectcmpInst->getPredicate() == CmpInst::ICMP_ULE ||
+ selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) {
+
+ auto op0 = selectcmpInst->getOperand(0);
+ auto op1 = selectcmpInst->getOperand(1);
+
+ IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
+ IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
+
+ /* this is probably not needed but we do it anyway */
+ if (!intTyOp0 || !intTyOp1) { continue; }
+
+ icomps.push_back(selectcmpInst);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ if (!icomps.size()) { return false; }
+
+ for (auto &IcmpInst : icomps) {
+
+ BasicBlock *bb = IcmpInst->getParent();
+
+ auto op0 = IcmpInst->getOperand(0);
+ auto op1 = IcmpInst->getOperand(1);
/* find out what the new predicate is going to be */
- auto pred = dyn_cast<CmpInst>(FcmpInst)->getPredicate();
+ auto pred = dyn_cast<CmpInst>(IcmpInst)->getPredicate();
CmpInst::Predicate new_pred;
switch (pred) {
- case CmpInst::FCMP_UGE:
- new_pred = CmpInst::FCMP_UGT;
+ case CmpInst::ICMP_UGE:
+ new_pred = CmpInst::ICMP_UGT;
break;
- case CmpInst::FCMP_OGE:
- new_pred = CmpInst::FCMP_OGT;
+ case CmpInst::ICMP_SGE:
+ new_pred = CmpInst::ICMP_SGT;
break;
- case CmpInst::FCMP_ULE:
- new_pred = CmpInst::FCMP_ULT;
+ case CmpInst::ICMP_ULE:
+ new_pred = CmpInst::ICMP_ULT;
break;
- case CmpInst::FCMP_OLE:
- new_pred = CmpInst::FCMP_OLT;
+ case CmpInst::ICMP_SLE:
+ new_pred = CmpInst::ICMP_SLT;
break;
default: // keep the compiler happy
continue;
@@ -265,25 +298,25 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
}
/* split before the icmp instruction */
- BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst));
+ BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(IcmpInst));
/* the old bb now contains a unconditional jump to the new one (end_bb)
* we need to delete it later */
/* create the ICMP instruction with new_pred and add it to the old basic
* block bb it is now at the position where the old IcmpInst was */
- Instruction *fcmp_np;
- fcmp_np = CmpInst::Create(Instruction::FCmp, new_pred, op0, op1);
+ Instruction *icmp_np;
+ icmp_np = CmpInst::Create(Instruction::ICmp, new_pred, op0, op1);
bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()),
- fcmp_np);
+ icmp_np);
- /* create a new basic block which holds the new EQ fcmp */
- Instruction *fcmp_eq;
+ /* create a new basic block which holds the new EQ icmp */
+ Instruction *icmp_eq;
/* insert middle_bb before end_bb */
BasicBlock *middle_bb =
BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
- fcmp_eq = CmpInst::Create(Instruction::FCmp, CmpInst::FCMP_OEQ, op0, op1);
- middle_bb->getInstList().push_back(fcmp_eq);
+ icmp_eq = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, op0, op1);
+ middle_bb->getInstList().push_back(icmp_eq);
/* add an unconditional branch to the end of middle_bb with destination
* end_bb */
BranchInst::Create(end_bb, middle_bb);
@@ -291,20 +324,20 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
/* replace the uncond branch with a conditional one, which depends on the
* new_pred icmp. True goes to end, false to the middle (injected) bb */
auto term = bb->getTerminator();
- BranchInst::Create(end_bb, middle_bb, fcmp_np, bb);
+ BranchInst::Create(end_bb, middle_bb, icmp_np, bb);
term->eraseFromParent();
/* replace the old IcmpInst (which is the first inst in end_bb) with a PHI
* inst to wire up the loose ends */
PHINode *PN = PHINode::Create(Int1Ty, 2, "");
/* the first result depends on the outcome of icmp_eq */
- PN->addIncoming(fcmp_eq, middle_bb);
+ PN->addIncoming(icmp_eq, middle_bb);
/* if the source was the original bb we know that the icmp_np yielded true
* hence we can hardcode this value */
PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb);
/* replace the old IcmpInst with our new and shiny PHI inst */
- BasicBlock::iterator ii(FcmpInst);
- ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN);
+ BasicBlock::iterator ii(IcmpInst);
+ ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN);
}
@@ -640,7 +673,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
BranchInst::Create(end_bb, signequal_bb);
- /* create a new bb which is executed if exponents are equal */
+ /* create a new bb which is executed if exponents are satisfying the compare
+ */
BasicBlock *middle_bb =
BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
@@ -695,7 +729,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
}
/* compare the exponents of the operands */
+ Instruction *icmp_exponents_equal;
Instruction *icmp_exponent_result;
+ BasicBlock * signequal2_bb = signequal_bb;
switch (FcmpInst->getPredicate()) {
case CmpInst::FCMP_OEQ:
@@ -707,22 +743,60 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_exponent_result =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, m_e0, m_e1);
break;
+ /* compare the exponents of the operands (signs are equal)
+ * if exponents are equal -> proceed to mantissa comparison
+ * else get result depending on sign
+ */
case CmpInst::FCMP_OGT:
case CmpInst::FCMP_UGT:
Instruction *icmp_exponent;
+ icmp_exponents_equal =
+ CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
+ signequal_bb->getInstList().insert(
+ BasicBlock::iterator(signequal_bb->getTerminator()),
+ icmp_exponents_equal);
+
+ // shortcut for unequal exponents
+ signequal2_bb = signequal_bb->splitBasicBlock(
+ BasicBlock::iterator(signequal_bb->getTerminator()));
+
+ /* if the exponents are equal goto middle_bb else to signequal2_bb */
+ term = signequal_bb->getTerminator();
+ BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal,
+ signequal_bb);
+ term->eraseFromParent();
+
icmp_exponent =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1);
- signequal_bb->getInstList().insert(
- BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent);
+ signequal2_bb->getInstList().insert(
+ BasicBlock::iterator(signequal2_bb->getTerminator()),
+ icmp_exponent);
icmp_exponent_result =
BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
break;
case CmpInst::FCMP_OLT:
case CmpInst::FCMP_ULT:
+ icmp_exponents_equal =
+ CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
+ signequal_bb->getInstList().insert(
+ BasicBlock::iterator(signequal_bb->getTerminator()),
+ icmp_exponents_equal);
+
+ // shortcut for unequal exponents
+ signequal2_bb = signequal_bb->splitBasicBlock(
+ BasicBlock::iterator(signequal_bb->getTerminator()));
+
+ /* if the exponents are equal goto middle_bb else to signequal2_bb */
+ term = signequal_bb->getTerminator();
+ BranchInst::Create(middle_bb, signequal2_bb, icmp_exponents_equal,
+ signequal_bb);
+ term->eraseFromParent();
+
icmp_exponent =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1);
- signequal_bb->getInstList().insert(
- BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent);
+ signequal2_bb->getInstList().insert(
+ BasicBlock::iterator(signequal2_bb->getTerminator()),
+ icmp_exponent);
icmp_exponent_result =
BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
break;
@@ -731,15 +805,40 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
}
- signequal_bb->getInstList().insert(
- BasicBlock::iterator(signequal_bb->getTerminator()),
+ signequal2_bb->getInstList().insert(
+ BasicBlock::iterator(signequal2_bb->getTerminator()),
icmp_exponent_result);
{
- auto term = signequal_bb->getTerminator();
- /* if the exponents are different do a fraction cmp */
- BranchInst::Create(middle_bb, end_bb, icmp_exponent_result, signequal_bb);
+ term = signequal2_bb->getTerminator();
+
+ switch (FcmpInst->getPredicate()) {
+
+ case CmpInst::FCMP_OEQ:
+ /* if the exponents are satifying the compare do a fraction cmp in
+ * middle_bb */
+ BranchInst::Create(middle_bb, end_bb, icmp_exponent_result,
+ signequal2_bb);
+ break;
+ case CmpInst::FCMP_ONE:
+ case CmpInst::FCMP_UNE:
+ /* if the exponents are satifying the compare do a fraction cmp in
+ * middle_bb */
+ BranchInst::Create(end_bb, middle_bb, icmp_exponent_result,
+ signequal2_bb);
+ break;
+ case CmpInst::FCMP_OGT:
+ case CmpInst::FCMP_UGT:
+ case CmpInst::FCMP_OLT:
+ case CmpInst::FCMP_ULT:
+ BranchInst::Create(end_bb, signequal2_bb);
+ break;
+ default:
+ continue;
+
+ }
+
term->eraseFromParent();
}
@@ -800,44 +899,82 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
/* compare the fractions of the operands */
Instruction *icmp_fraction_result;
+ Instruction *icmp_fraction_result2;
+ BasicBlock * middle2_bb = middle_bb;
+ PHINode * PN2 = nullptr;
switch (FcmpInst->getPredicate()) {
case CmpInst::FCMP_OEQ:
icmp_fraction_result =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1);
+ middle2_bb->getInstList().insert(
+ BasicBlock::iterator(middle2_bb->getTerminator()),
+ icmp_fraction_result);
+
break;
case CmpInst::FCMP_UNE:
case CmpInst::FCMP_ONE:
icmp_fraction_result =
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1);
+ middle2_bb->getInstList().insert(
+ BasicBlock::iterator(middle2_bb->getTerminator()),
+ icmp_fraction_result);
+
break;
case CmpInst::FCMP_OGT:
case CmpInst::FCMP_UGT:
- Instruction *icmp_fraction;
- icmp_fraction =
- CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
- middle_bb->getInstList().insert(
- BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction);
- icmp_fraction_result =
- BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
- break;
case CmpInst::FCMP_OLT:
- case CmpInst::FCMP_ULT:
- icmp_fraction =
- CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
- middle_bb->getInstList().insert(
- BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction);
- icmp_fraction_result =
- BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
- break;
+ case CmpInst::FCMP_ULT: {
+
+ middle2_bb = middle_bb->splitBasicBlock(
+ BasicBlock::iterator(middle_bb->getTerminator()));
+
+ BasicBlock *negative_bb = BasicBlock::Create(
+ C, "negative_value", middle2_bb->getParent(), middle2_bb);
+ BasicBlock *positive_bb = BasicBlock::Create(
+ C, "positive_value", negative_bb->getParent(), negative_bb);
+
+ if (FcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
+ FcmpInst->getPredicate() == CmpInst::FCMP_UGT) {
+
+ negative_bb->getInstList().push_back(
+ icmp_fraction_result = CmpInst::Create(
+ Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1));
+ positive_bb->getInstList().push_back(
+ icmp_fraction_result2 = CmpInst::Create(
+ Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1));
+
+ } else {
+
+ negative_bb->getInstList().push_back(
+ icmp_fraction_result = CmpInst::Create(
+ Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1));
+ positive_bb->getInstList().push_back(
+ icmp_fraction_result2 = CmpInst::Create(
+ Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1));
+
+ }
+
+ BranchInst::Create(middle2_bb, negative_bb);
+ BranchInst::Create(middle2_bb, positive_bb);
+
+ term = middle_bb->getTerminator();
+ BranchInst::Create(negative_bb, positive_bb, t_s0, middle_bb);
+ term->eraseFromParent();
+
+ PN2 = PHINode::Create(Int1Ty, 2, "");
+ PN2->addIncoming(icmp_fraction_result, negative_bb);
+ PN2->addIncoming(icmp_fraction_result2, positive_bb);
+ middle2_bb->getInstList().insert(
+ BasicBlock::iterator(middle2_bb->getTerminator()), PN2);
+
+ } break;
+
default:
continue;
}
- middle_bb->getInstList().insert(
- BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction_result);
-
PHINode *PN = PHINode::Create(Int1Ty, 3, "");
switch (FcmpInst->getPredicate()) {
@@ -849,7 +986,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
/* unequal exponents cannot be equal values, too */
PN->addIncoming(ConstantInt::get(Int1Ty, 0), signequal_bb);
/* fractions comparison */
- PN->addIncoming(icmp_fraction_result, middle_bb);
+ PN->addIncoming(icmp_fraction_result, middle2_bb);
break;
case CmpInst::FCMP_ONE:
case CmpInst::FCMP_UNE:
@@ -857,25 +994,25 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
/* goto true branch */
PN->addIncoming(ConstantInt::get(Int1Ty, 1), bb);
/* unequal exponents are unequal values, too */
- PN->addIncoming(ConstantInt::get(Int1Ty, 1), signequal_bb);
+ PN->addIncoming(icmp_exponent_result, signequal_bb);
/* fractions comparison */
- PN->addIncoming(icmp_fraction_result, middle_bb);
+ PN->addIncoming(icmp_fraction_result, middle2_bb);
break;
case CmpInst::FCMP_OGT:
case CmpInst::FCMP_UGT:
/* if op1 is negative goto true branch,
else go on comparing */
PN->addIncoming(t_s1, bb);
- PN->addIncoming(icmp_exponent_result, signequal_bb);
- PN->addIncoming(icmp_fraction_result, middle_bb);
+ PN->addIncoming(icmp_exponent_result, signequal2_bb);
+ PN->addIncoming(PN2, middle2_bb);
break;
case CmpInst::FCMP_OLT:
case CmpInst::FCMP_ULT:
/* if op0 is negative goto true branch,
else go on comparing */
PN->addIncoming(t_s0, bb);
- PN->addIncoming(icmp_exponent_result, signequal_bb);
- PN->addIncoming(icmp_fraction_result, middle_bb);
+ PN->addIncoming(icmp_exponent_result, signequal2_bb);
+ PN->addIncoming(PN2, middle2_bb);
break;
default:
continue;
@@ -1107,7 +1244,8 @@ size_t SplitComparesTransform::splitIntCompares(Module &M, unsigned bitw) {
bool SplitComparesTransform::runOnModule(Module &M) {
- int bitw = 64;
+ int bitw = 64;
+ size_t count;
char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
@@ -1115,30 +1253,44 @@ bool SplitComparesTransform::runOnModule(Module &M) {
enableFPSplit = getenv("AFL_LLVM_LAF_SPLIT_FLOATS") != NULL;
- simplifyCompares(M);
-
- simplifyIntSignedness(M);
-
if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
getenv("AFL_DEBUG") != NULL) {
errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
"heiko@hexco.de\n";
- if (enableFPSplit)
- errs() << "Split-floatingpoint-compare-pass: " << splitFPCompares(M)
+ } else {
+
+ be_quiet = 1;
+
+ }
+
+ if (enableFPSplit) {
+
+ count = splitFPCompares(M);
+
+ if (!be_quiet) {
+
+ errs() << "Split-floatingpoint-compare-pass: " << count
<< " FP comparisons splitted\n";
- } else
+ }
- be_quiet = 1;
+ simplifyFPCompares(M);
+
+ }
+
+ simplifyCompares(M);
+
+ simplifyIntSignedness(M);
switch (bitw) {
case 64:
+ count = splitIntCompares(M, bitw);
if (!be_quiet)
- errs() << "Split-integer-compare-pass " << bitw
- << "bit: " << splitIntCompares(M, bitw) << " splitted\n";
+ errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
+ << " splitted\n";
bitw >>= 1;
#if LLVM_VERSION_MAJOR > 3 || \
@@ -1146,9 +1298,10 @@ bool SplitComparesTransform::runOnModule(Module &M) {
[[clang::fallthrough]]; /*FALLTHRU*/ /* FALLTHROUGH */
#endif
case 32:
+ count = splitIntCompares(M, bitw);
if (!be_quiet)
- errs() << "Split-integer-compare-pass " << bitw
- << "bit: " << splitIntCompares(M, bitw) << " splitted\n";
+ errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
+ << " splitted\n";
bitw >>= 1;
#if LLVM_VERSION_MAJOR > 3 || \
@@ -1156,9 +1309,10 @@ bool SplitComparesTransform::runOnModule(Module &M) {
[[clang::fallthrough]]; /*FALLTHRU*/ /* FALLTHROUGH */
#endif
case 16:
+ count = splitIntCompares(M, bitw);
if (!be_quiet)
- errs() << "Split-integer-compare-pass " << bitw
- << "bit: " << splitIntCompares(M, bitw) << " splitted\n";
+ errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
+ << " splitted\n";
bitw >>= 1;
break;
diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc
index 44075c94..f025df77 100644
--- a/llvm_mode/split-switches-pass.so.cc
+++ b/llvm_mode/split-switches-pass.so.cc
@@ -91,9 +91,6 @@ class SplitSwitchesTransform : public ModulePass {
typedef std::vector<CaseExpr> CaseVector;
- protected:
- int be_quiet = 0;
-
private:
bool splitSwitches(Module &M);
bool transformCmps(Module &M, const bool processStrcmp,