about summary refs log tree commit diff
path: root/gcc_plugin
diff options
context:
space:
mode:
Diffstat (limited to 'gcc_plugin')
-rw-r--r--gcc_plugin/Makefile6
-rw-r--r--gcc_plugin/README.gcc.md8
-rw-r--r--gcc_plugin/afl-gcc-fast.c4
-rw-r--r--gcc_plugin/afl-gcc-pass.so.cc37
-rw-r--r--gcc_plugin/afl-gcc-rt.o.c14
5 files changed, 46 insertions, 23 deletions
diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile
index 287b6545..c7d9796b 100644
--- a/gcc_plugin/Makefile
+++ b/gcc_plugin/Makefile
@@ -71,8 +71,8 @@ endif
 test_deps:
 	@echo "[*] Checking for working '$(CC)'..."
 	@which $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 )
-	@echo "[*] Checking for gcc for plugin support..."
-	@$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 )
+#	@echo "[*] Checking for gcc for plugin support..."
+#	@$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 )
 	@echo "[*] Checking for gcc plugin development header files..."
 	@test -d `$(CC) -print-file-name=plugin`/include || ( echo "[-] Oops, can't find gcc header files. Be sure to install 'gcc-X-plugin-dev'."; exit 1 )
 	@echo "[*] Checking for '../afl-showmap'..."
@@ -80,7 +80,7 @@ test_deps:
 	@echo "[+] All set and ready to build."
 
 ../afl-gcc-fast: afl-gcc-fast.c | test_deps
-	$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
+	$(CC) -DAFL_GCC_CC=\"$(CC)\" -DAFL_GCC_CXX=\"$(CXX)\" $(CFLAGS) $< -o $@ $(LDFLAGS)
 	ln -sf afl-gcc-fast ../afl-g++-fast
 
 ../afl-gcc-pass.so: afl-gcc-pass.so.cc | test_deps
diff --git a/gcc_plugin/README.gcc.md b/gcc_plugin/README.gcc.md
index 676ef427..80fccfb6 100644
--- a/gcc_plugin/README.gcc.md
+++ b/gcc_plugin/README.gcc.md
@@ -46,9 +46,11 @@ should be all you need. On Debian machines, these headers can be acquired by
 installing the `gcc-<VERSION>-plugin-dev` packages.
 
 To build the instrumentation itself, type 'make'. This will generate binaries
-called afl-gcc-fast and afl-g++-fast in the parent directory. Once this
-is done, you can instrument third-party code in a way similar to the standard
-operating mode of AFL, e.g.:
+called afl-gcc-fast and afl-g++-fast in the parent directory. 
+If the CC/CXX have been overridden, those compilers will be used from
+those wrappers without using AFL_CXX/AFL_CC settings.
+Once this is done, you can instrument third-party code in a way similar to the
+standard operating mode of AFL, e.g.:
 
   CC=/path/to/afl/afl-gcc-fast ./configure [...options...]
   make
diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c
index 057b44cc..68035944 100644
--- a/gcc_plugin/afl-gcc-fast.c
+++ b/gcc_plugin/afl-gcc-fast.c
@@ -119,12 +119,12 @@ static void edit_params(u32 argc, char** argv) {
   if (!strcmp(name, "afl-g++-fast")) {
 
     u8* alt_cxx = getenv("AFL_CXX");
-    cc_params[0] = alt_cxx ? alt_cxx : (u8*)"g++";
+    cc_params[0] = alt_cxx ? alt_cxx : (u8*)AFL_GCC_CXX;
 
   } else {
 
     u8* alt_cc = getenv("AFL_CC");
-    cc_params[0] = alt_cc ? alt_cc : (u8*)"gcc";
+    cc_params[0] = alt_cc ? alt_cc : (u8*)AFL_GCC_CC;
 
   }
 
diff --git a/gcc_plugin/afl-gcc-pass.so.cc b/gcc_plugin/afl-gcc-pass.so.cc
index 84e02cb8..bf16b14b 100644
--- a/gcc_plugin/afl-gcc-pass.so.cc
+++ b/gcc_plugin/afl-gcc-pass.so.cc
@@ -128,6 +128,7 @@ static unsigned int ext_call_instrument(function *fun) {
     int           more_than_one = -1;
     edge          ep;
     edge_iterator eip;
+
     FOR_EACH_EDGE(ep, eip, bb->preds) {
 
       int count = 0;
@@ -222,6 +223,7 @@ static unsigned int inline_instrument(function *fun) {
   DECL_EXTERNAL(prev_loc_g) = 1;                        /* External linkage */
   DECL_PRESERVE_P(prev_loc_g) = 1;
   DECL_ARTIFICIAL(prev_loc_g) = 1;                  /* Injected by compiler */
+  set_decl_tls_model(prev_loc_g, TLS_MODEL_REAL);          /* TLS attribute */
   rest_of_decl_compilation(prev_loc_g, 1, 0);
 
   FOR_EACH_BB_FN(bb, fun) {
@@ -293,6 +295,7 @@ static unsigned int inline_instrument(function *fun) {
     gimple_seq_add_stmt(&seq, g);  // map_ptr = __afl_area_ptr
     update_stmt(g);
 
+#if 1
 #if 0
 		tree addr = build2(ADDR_EXPR, map_type, map_ptr, area_off);
 		g = gimple_build_assign(map_ptr2, MODIFY_EXPR, addr);
@@ -303,12 +306,21 @@ static unsigned int inline_instrument(function *fun) {
     gimple_seq_add_stmt(&seq, g);  // map_ptr2 = map_ptr + area_off
     update_stmt(g);
 #endif
+
     // gimple_assign <mem_ref, _3, *p_6, NULL, NULL>
     tree tmp1 = create_tmp_var_raw(unsigned_char_type_node, "tmp1");
     g = gimple_build_assign(tmp1, MEM_REF, map_ptr2);
     gimple_seq_add_stmt(&seq, g);  // tmp1 = *map_ptr2
     update_stmt(g);
-
+#else
+    tree atIndex = build2(PLUS_EXPR, uint32_type_node, map_ptr, area_off);
+    tree array_address = build1(ADDR_EXPR, map_type, atIndex);
+    tree array_access = build1(INDIRECT_REF, map_type, array_address);
+    tree tmp1 = create_tmp_var(unsigned_char_type_node, "tmp1");
+    g = gimple_build_assign(tmp1, array_access);
+    gimple_seq_add_stmt(&seq, g);  // tmp1 = *(map_ptr + area_off)
+    update_stmt(g);
+#endif
     // gimple_assign <plus_expr, _4, _3, 1, NULL>
     tree tmp2 = create_tmp_var_raw(unsigned_char_type_node, "tmp2");
     g = gimple_build_assign(tmp2, PLUS_EXPR, tmp1, one);
@@ -320,8 +332,8 @@ static unsigned int inline_instrument(function *fun) {
 
     // gimple_assign <ssa_name, *p_6, _4, NULL, NULL>
     //		tree map_ptr3 = create_tmp_var_raw(map_type, "map_ptr3");
-    g = gimple_build_assign(map_ptr_g, INDIRECT_REF, tmp2);
-    gimple_seq_add_stmt(&seq, g);  // *map_ptr3 = tmp2
+    g = gimple_build_assign(map_ptr2, INDIRECT_REF, tmp2);
+    gimple_seq_add_stmt(&seq, g);  // *map_ptr2 = tmp2
     update_stmt(g);
 
     /* Set prev_loc to cur_loc >> 1 */
@@ -401,11 +413,13 @@ class afl_pass : public gimple_opt_pass {
 
   }
 
-  virtual unsigned int execute(function *fun) {
+  unsigned int execute(function *fun) override {
 
     if (!myWhitelist.empty()) {
 
       bool instrumentBlock = false;
+      std::string instFilename;
+      unsigned int instLine = 0;
 
       /* EXPR_FILENAME
       This macro returns the name of the file in which the entity was declared,
@@ -417,7 +431,8 @@ class afl_pass : public gimple_opt_pass {
       if (0 != strncmp("<internal>", fname, 10) &&
           0 != strncmp("<built-in>", fname, 10)) {
 
-        std::string instFilename(fname);
+        instFilename = fname;
+        instLine = DECL_SOURCE_LINE(fun->decl);
 
         /* Continue only if we know where we actually are */
         if (!instFilename.empty()) {
@@ -449,7 +464,17 @@ class afl_pass : public gimple_opt_pass {
 
       /* Either we couldn't figure out our location or the location is
        * not whitelisted, so we skip instrumentation. */
-      if (!instrumentBlock) return 0;
+      if (!instrumentBlock) {
+
+        if (!be_quiet) {
+             if (!instFilename.empty())
+               SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s line %u...\n",
+                    instFilename.c_str(), instLine);
+             else
+               SAYF(cYEL "[!] " cBRI "No filename information found, skipping it");
+        }
+        return 0;
+      }
 
     }
 
diff --git a/gcc_plugin/afl-gcc-rt.o.c b/gcc_plugin/afl-gcc-rt.o.c
index 5b70a247..1fb9e099 100644
--- a/gcc_plugin/afl-gcc-rt.o.c
+++ b/gcc_plugin/afl-gcc-rt.o.c
@@ -9,8 +9,6 @@
    GCC integration design is based on the LLVM design, which comes
    from Laszlo Szekeres.
 
-   Copyright 2015 Google Inc. All rights reserved.
-
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at:
@@ -55,15 +53,13 @@ __thread u32 __afl_prev_loc;
 #endif
 
 /* Trace a basic block with some ID */
-void __afl_trace(u32 x) {
-
-  u32 l = __afl_prev_loc;
+void __afl_trace(const u32 x) {
 
-#if 0 /* enable for neverZero feature. By default disabled since too inefficient :-( */
-  /* @Marc: avoid conditional jumps here */
-  __afl_area_ptr[l ^ x] += 1 + (__afl_area_ptr[l ^ x] == (u8)~0);
+#if 1 /* enable for neverZero feature. */
+  __afl_area_ptr[__afl_prev_loc ^ x] += 1 
+                               + ((u8)(1 + __afl_area_ptr[__afl_prev_loc ^ x]) == 0);
 #else
-  ++__afl_area_ptr[l ^ x];
+  ++__afl_area_ptr[__afl_prev_loc ^ x];
 #endif
 
   __afl_prev_loc = (x >> 1);