about summary refs log tree commit diff
path: root/instrumentation/afl-compiler-rt.o.c
diff options
context:
space:
mode:
Diffstat (limited to 'instrumentation/afl-compiler-rt.o.c')
-rw-r--r--instrumentation/afl-compiler-rt.o.c448
1 files changed, 369 insertions, 79 deletions
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index e31bff16..3a9e3e0e 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -70,7 +70,7 @@
    run. It will end up as .comm, so it shouldn't be too wasteful. */
 
 #if MAP_SIZE <= 65536
-  #define MAP_INITIAL_SIZE 256000
+  #define MAP_INITIAL_SIZE 2097152
 #else
   #define MAP_INITIAL_SIZE MAP_SIZE
 #endif
@@ -161,7 +161,7 @@ void send_forkserver_error(int error) {
   u32 status;
   if (!error || error > 0xffff) return;
   status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error));
-  if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) return;
+  if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) { return; }
 
 }
 
@@ -368,8 +368,8 @@ static void __afl_map_shm(void) {
 
     if (__afl_map_size && __afl_map_size > MAP_SIZE) {
 
-      u8 *map_env = getenv("AFL_MAP_SIZE");
-      if (!map_env || atoi(map_env) < MAP_SIZE) {
+      u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
+      if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
 
         send_forkserver_error(FS_ERROR_MAP_SIZE);
         _exit(1);
@@ -378,7 +378,7 @@ static void __afl_map_shm(void) {
 
     }
 
-    __afl_area_ptr = shmat(shm_id, (void *)__afl_map_addr, 0);
+    __afl_area_ptr = (u8 *)shmat(shm_id, (void *)__afl_map_addr, 0);
 
     /* Whooooops. */
 
@@ -405,9 +405,9 @@ static void __afl_map_shm(void) {
 
              __afl_map_addr) {
 
-    __afl_area_ptr =
-        mmap((void *)__afl_map_addr, __afl_map_size, PROT_READ | PROT_WRITE,
-             MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+    __afl_area_ptr = (u8 *)mmap(
+        (void *)__afl_map_addr, __afl_map_size, PROT_READ | PROT_WRITE,
+        MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
 
     if (__afl_area_ptr == MAP_FAILED) {
 
@@ -425,7 +425,7 @@ static void __afl_map_shm(void) {
 
     if (__afl_final_loc > MAP_INITIAL_SIZE) {
 
-      __afl_area_ptr = malloc(__afl_final_loc);
+      __afl_area_ptr = (u8 *)malloc(__afl_final_loc);
 
     }
 
@@ -439,7 +439,7 @@ static void __afl_map_shm(void) {
 
     if (__afl_map_size > MAP_INITIAL_SIZE) {
 
-      __afl_area_ptr_dummy = malloc(__afl_map_size);
+      __afl_area_ptr_dummy = (u8 *)malloc(__afl_map_size);
 
       if (__afl_area_ptr_dummy) {
 
@@ -505,7 +505,7 @@ static void __afl_map_shm(void) {
 #else
     u32 shm_id = atoi(id_str);
 
-    __afl_cmp_map = shmat(shm_id, NULL, 0);
+    __afl_cmp_map = (struct cmp_map *)shmat(shm_id, NULL, 0);
 #endif
 
     __afl_cmp_map_backup = __afl_cmp_map;
@@ -544,11 +544,11 @@ static void __afl_start_snapshots(void) {
   if (__afl_dictionary_len && __afl_dictionary) status |= FS_OPT_AUTODICT;
   memcpy(tmp, &status, 4);
 
-  if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
+  if (write(FORKSRV_FD + 1, tmp, 4) != 4) { return; }
 
   if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) {
 
-    if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
+    if (read(FORKSRV_FD, &was_killed, 4) != 4) { _exit(1); }
 
     if (getenv("AFL_DEBUG")) {
 
@@ -1090,7 +1090,7 @@ __attribute__((constructor(0))) void __afl_auto_first(void) {
   if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return;
   u8 *ptr;
 
-  ptr = (u8 *)malloc(1024000);
+  ptr = (u8 *)malloc(2097152);
 
   if (ptr && (ssize_t)ptr != -1) {
 
@@ -1169,8 +1169,9 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
 
   if (getenv("AFL_DEBUG")) {
 
-    fprintf(stderr, "Running __sanitizer_cov_trace_pc_guard_init: %p-%p\n",
-            start, stop);
+    fprintf(stderr,
+            "Running __sanitizer_cov_trace_pc_guard_init: %p-%p (%lu edges)\n",
+            start, stop, stop - start);
 
   }
 
@@ -1207,22 +1208,33 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
 
 ///// CmpLog instrumentation
 
-void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2) {
+void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr) {
 
-  if (unlikely(!__afl_cmp_map)) return;
+  // fprintf(stderr, "hook1 arg0=%02x arg1=%02x attr=%u\n",
+  //         (u8) arg1, (u8) arg2, attr);
+
+  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (k >> 4) ^ (k << 8);
   k &= CMP_MAP_W - 1;
 
-  __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+  u32 hits;
 
-  u32 hits = __afl_cmp_map->headers[k].hits;
-  __afl_cmp_map->headers[k].hits = hits + 1;
-  // if (!__afl_cmp_map->headers[k].cnt)
-  //  __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++;
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) {
 
-  __afl_cmp_map->headers[k].shape = 0;
+    __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+    hits = 0;
+    __afl_cmp_map->headers[k].hits = 1;
+    __afl_cmp_map->headers[k].shape = 0;
+
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits++;
+
+  }
+
+  __afl_cmp_map->headers[k].attribute = attr;
 
   hits &= CMP_MAP_H - 1;
   __afl_cmp_map->log[k][hits].v0 = arg1;
@@ -1230,20 +1242,36 @@ void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2) {
 
 }
 
-void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2) {
+void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2, uint8_t attr) {
 
-  if (unlikely(!__afl_cmp_map)) return;
+  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (k >> 4) ^ (k << 8);
   k &= CMP_MAP_W - 1;
 
-  __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+  u32 hits;
 
-  u32 hits = __afl_cmp_map->headers[k].hits;
-  __afl_cmp_map->headers[k].hits = hits + 1;
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) {
 
-  __afl_cmp_map->headers[k].shape = 1;
+    __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+    hits = 0;
+    __afl_cmp_map->headers[k].hits = 1;
+    __afl_cmp_map->headers[k].shape = 1;
+
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits++;
+
+    if (!__afl_cmp_map->headers[k].shape) {
+
+      __afl_cmp_map->headers[k].shape = 1;
+
+    }
+
+  }
+
+  __afl_cmp_map->headers[k].attribute = attr;
 
   hits &= CMP_MAP_H - 1;
   __afl_cmp_map->log[k][hits].v0 = arg1;
@@ -1251,20 +1279,38 @@ void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2) {
 
 }
 
-void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2) {
+void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2, uint8_t attr) {
 
-  if (unlikely(!__afl_cmp_map)) return;
+  // fprintf(stderr, "hook4 arg0=%x arg1=%x attr=%u\n", arg1, arg2, attr);
+
+  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (k >> 4) ^ (k << 8);
   k &= CMP_MAP_W - 1;
 
-  __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+  u32 hits;
 
-  u32 hits = __afl_cmp_map->headers[k].hits;
-  __afl_cmp_map->headers[k].hits = hits + 1;
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) {
 
-  __afl_cmp_map->headers[k].shape = 3;
+    __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+    hits = 0;
+    __afl_cmp_map->headers[k].hits = 1;
+    __afl_cmp_map->headers[k].shape = 3;
+
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits++;
+
+    if (__afl_cmp_map->headers[k].shape < 3) {
+
+      __afl_cmp_map->headers[k].shape = 3;
+
+    }
+
+  }
+
+  __afl_cmp_map->headers[k].attribute = attr;
 
   hits &= CMP_MAP_H - 1;
   __afl_cmp_map->log[k][hits].v0 = arg1;
@@ -1272,20 +1318,38 @@ void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2) {
 
 }
 
-void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2) {
+void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr) {
 
-  if (unlikely(!__afl_cmp_map)) return;
+  // fprintf(stderr, "hook8 arg0=%lx arg1=%lx attr=%u\n", arg1, arg2, attr);
+
+  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (k >> 4) ^ (k << 8);
   k &= CMP_MAP_W - 1;
 
-  __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+  u32 hits;
 
-  u32 hits = __afl_cmp_map->headers[k].hits;
-  __afl_cmp_map->headers[k].hits = hits + 1;
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) {
+
+    __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+    hits = 0;
+    __afl_cmp_map->headers[k].hits = 1;
+    __afl_cmp_map->headers[k].shape = 7;
+
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits++;
+
+    if (__afl_cmp_map->headers[k].shape < 7) {
+
+      __afl_cmp_map->headers[k].shape = 7;
+
+    }
+
+  }
 
-  __afl_cmp_map->headers[k].shape = 7;
+  __afl_cmp_map->headers[k].attribute = attr;
 
   hits &= CMP_MAP_H - 1;
   __afl_cmp_map->log[k][hits].v0 = arg1;
@@ -1293,35 +1357,154 @@ void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2) {
 
 }
 
-#if defined(__APPLE__)
-  #pragma weak __sanitizer_cov_trace_const_cmp1 = __cmplog_ins_hook1
-  #pragma weak __sanitizer_cov_trace_const_cmp2 = __cmplog_ins_hook2
-  #pragma weak __sanitizer_cov_trace_const_cmp4 = __cmplog_ins_hook4
-  #pragma weak __sanitizer_cov_trace_const_cmp8 = __cmplog_ins_hook8
+#ifdef WORD_SIZE_64
+// support for u24 to u120 via llvm _ExitInt(). size is in bytes minus 1
+void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr,
+                        uint8_t size) {
 
-  #pragma weak __sanitizer_cov_trace_cmp1 = __cmplog_ins_hook1
-  #pragma weak __sanitizer_cov_trace_cmp2 = __cmplog_ins_hook2
-  #pragma weak __sanitizer_cov_trace_cmp4 = __cmplog_ins_hook4
-  #pragma weak __sanitizer_cov_trace_cmp8 = __cmplog_ins_hook8
-#else
-void __sanitizer_cov_trace_const_cmp1(uint8_t arg1, uint8_t arg2)
-    __attribute__((alias("__cmplog_ins_hook1")));
-void __sanitizer_cov_trace_const_cmp2(uint16_t arg1, uint16_t arg2)
-    __attribute__((alias("__cmplog_ins_hook2")));
-void __sanitizer_cov_trace_const_cmp4(uint32_t arg1, uint32_t arg2)
-    __attribute__((alias("__cmplog_ins_hook4")));
-void __sanitizer_cov_trace_const_cmp8(uint64_t arg1, uint64_t arg2)
-    __attribute__((alias("__cmplog_ins_hook8")));
-
-void __sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2)
-    __attribute__((alias("__cmplog_ins_hook1")));
-void __sanitizer_cov_trace_cmp2(uint16_t arg1, uint16_t arg2)
-    __attribute__((alias("__cmplog_ins_hook2")));
-void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2)
-    __attribute__((alias("__cmplog_ins_hook4")));
-void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2)
-    __attribute__((alias("__cmplog_ins_hook8")));
-#endif                                                /* defined(__APPLE__) */
+  // fprintf(stderr, "hookN arg0=%llx:%llx arg1=%llx:%llx bytes=%u attr=%u\n",
+  // (u64)(arg1 >> 64), (u64)arg1, (u64)(arg2 >> 64), (u64)arg2, size + 1,
+  // attr);
+
+  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
+
+  uintptr_t k = (uintptr_t)__builtin_return_address(0);
+  k = (k >> 4) ^ (k << 8);
+  k &= CMP_MAP_W - 1;
+
+  u32 hits;
+
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) {
+
+    __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+    hits = 0;
+    __afl_cmp_map->headers[k].hits = 1;
+    __afl_cmp_map->headers[k].shape = size;
+
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits++;
+
+    if (__afl_cmp_map->headers[k].shape < size) {
+
+      __afl_cmp_map->headers[k].shape = size;
+
+    }
+
+  }
+
+  __afl_cmp_map->headers[k].attribute = attr;
+
+  hits &= CMP_MAP_H - 1;
+  __afl_cmp_map->log[k][hits].v0 = (u64)arg1;
+  __afl_cmp_map->log[k][hits].v1 = (u64)arg2;
+
+  if (size > 7) {
+
+    __afl_cmp_map->log[k][hits].v0_128 = (u64)(arg1 >> 64);
+    __afl_cmp_map->log[k][hits].v1_128 = (u64)(arg2 >> 64);
+
+  }
+
+}
+
+void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2, uint8_t attr) {
+
+  if (unlikely(!__afl_cmp_map)) return;
+
+  uintptr_t k = (uintptr_t)__builtin_return_address(0);
+  k = (k >> 4) ^ (k << 8);
+  k &= CMP_MAP_W - 1;
+
+  u32 hits;
+
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) {
+
+    __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+    hits = 0;
+    __afl_cmp_map->headers[k].hits = 1;
+    __afl_cmp_map->headers[k].shape = 15;
+
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits++;
+
+    if (__afl_cmp_map->headers[k].shape < 15) {
+
+      __afl_cmp_map->headers[k].shape = 15;
+
+    }
+
+  }
+
+  __afl_cmp_map->headers[k].attribute = attr;
+
+  hits &= CMP_MAP_H - 1;
+  __afl_cmp_map->log[k][hits].v0 = (u64)arg1;
+  __afl_cmp_map->log[k][hits].v1 = (u64)arg2;
+  __afl_cmp_map->log[k][hits].v0_128 = (u64)(arg1 >> 64);
+  __afl_cmp_map->log[k][hits].v1_128 = (u64)(arg2 >> 64);
+
+}
+
+#endif
+
+void __sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2) {
+
+  __cmplog_ins_hook1(arg1, arg2, 0);
+
+}
+
+void __sanitizer_cov_trace_const_cmp1(uint8_t arg1, uint8_t arg2) {
+
+  __cmplog_ins_hook1(arg1, arg2, 0);
+
+}
+
+void __sanitizer_cov_trace_cmp2(uint16_t arg1, uint16_t arg2) {
+
+  __cmplog_ins_hook2(arg1, arg2, 0);
+
+}
+
+void __sanitizer_cov_trace_const_cmp2(uint16_t arg1, uint16_t arg2) {
+
+  __cmplog_ins_hook2(arg1, arg2, 0);
+
+}
+
+void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2) {
+
+  __cmplog_ins_hook4(arg1, arg2, 0);
+
+}
+
+void __sanitizer_cov_trace_cost_cmp4(uint32_t arg1, uint32_t arg2) {
+
+  __cmplog_ins_hook4(arg1, arg2, 0);
+
+}
+
+void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2) {
+
+  __cmplog_ins_hook8(arg1, arg2, 0);
+
+}
+
+void __sanitizer_cov_trace_const_cmp8(uint64_t arg1, uint64_t arg2) {
+
+  __cmplog_ins_hook8(arg1, arg2, 0);
+
+}
+
+#ifdef WORD_SIZE_64
+void __sanitizer_cov_trace_cmp16(uint128_t arg1, uint128_t arg2) {
+
+  __cmplog_ins_hook16(arg1, arg2, 0);
+
+}
+
+#endif
 
 void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
 
@@ -1333,12 +1516,28 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
     k = (k >> 4) ^ (k << 8);
     k &= CMP_MAP_W - 1;
 
-    __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+    u32 hits;
 
-    u32 hits = __afl_cmp_map->headers[k].hits;
-    __afl_cmp_map->headers[k].hits = hits + 1;
+    if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS) {
 
-    __afl_cmp_map->headers[k].shape = 7;
+      __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+      hits = 0;
+      __afl_cmp_map->headers[k].hits = 1;
+      __afl_cmp_map->headers[k].shape = 7;
+
+    } else {
+
+      hits = __afl_cmp_map->headers[k].hits++;
+
+      if (__afl_cmp_map->headers[k].shape < 7) {
+
+        __afl_cmp_map->headers[k].shape = 7;
+
+      }
+
+    }
+
+    __afl_cmp_map->headers[k].attribute = 1;
 
     hits &= CMP_MAP_H - 1;
     __afl_cmp_map->log[k][hits].v0 = val;
@@ -1353,7 +1552,7 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
 // to avoid to call it on .text addresses
 static int area_is_mapped(void *ptr, size_t len) {
 
-  char *p = ptr;
+  char *p = (char *)ptr;
   char *page = (char *)((uintptr_t)p & ~(sysconf(_SC_PAGE_SIZE) - 1));
 
   int r = msync(page, (p - page) + len, MS_ASYNC);
@@ -1364,6 +1563,18 @@ static int area_is_mapped(void *ptr, size_t len) {
 
 void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
 
+  /*
+    u32 i;
+    if (!area_is_mapped(ptr1, 32) || !area_is_mapped(ptr2, 32)) return;
+    fprintf(stderr, "rtn arg0=");
+    for (i = 0; i < 24; i++)
+      fprintf(stderr, "%02x", ptr1[i]);
+    fprintf(stderr, " arg1=");
+    for (i = 0; i < 24; i++)
+      fprintf(stderr, "%02x", ptr2[i]);
+    fprintf(stderr, "\n");
+  */
+
   if (unlikely(!__afl_cmp_map)) return;
 
   if (!area_is_mapped(ptr1, 32) || !area_is_mapped(ptr2, 32)) return;
@@ -1372,12 +1583,26 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
   k = (k >> 4) ^ (k << 8);
   k &= CMP_MAP_W - 1;
 
-  __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+  u32 hits;
+
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
+
+    __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+    hits = 0;
+    __afl_cmp_map->headers[k].hits = 1;
+    __afl_cmp_map->headers[k].shape = 31;
+
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits++;
+
+    if (__afl_cmp_map->headers[k].shape < 31) {
+
+      __afl_cmp_map->headers[k].shape = 31;
 
-  u32 hits = __afl_cmp_map->headers[k].hits;
-  __afl_cmp_map->headers[k].hits = hits + 1;
+    }
 
-  __afl_cmp_map->headers[k].shape = 31;
+  }
 
   hits &= CMP_MAP_RTN_H - 1;
   __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0,
@@ -1387,6 +1612,71 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
 
 }
 
+// gcc libstdc++
+// _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEPKc
+static u8 *get_gcc_stdstring(u8 *string) {
+
+  u32 *len = (u32 *)(string + 8);
+
+  if (*len < 16) {  // in structure
+
+    return (string + 16);
+
+  } else {  // in memory
+
+    u8 **ptr = (u8 **)string;
+    return (*ptr);
+
+  }
+
+}
+
+// llvm libc++ _ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocator
+//             IcEEE7compareEmmPKcm
+static u8 *get_llvm_stdstring(u8 *string) {
+
+  // length is in: if ((string[0] & 1) == 0) u8 len = (string[0] >> 1);
+  // or: if (string[0] & 1) u32 *len = (u32 *) (string + 8);
+
+  if (string[0] & 1) {  // in memory
+
+    u8 **ptr = (u8 **)(string + 16);
+    return (*ptr);
+
+  } else {  // in structure
+
+    return (string + 1);
+
+  }
+
+}
+
+void __cmplog_rtn_gcc_stdstring_cstring(u8 *stdstring, u8 *cstring) {
+
+  __cmplog_rtn_hook(get_gcc_stdstring(stdstring), cstring);
+
+}
+
+void __cmplog_rtn_gcc_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) {
+
+  __cmplog_rtn_hook(get_gcc_stdstring(stdstring1),
+                    get_gcc_stdstring(stdstring2));
+
+}
+
+void __cmplog_rtn_llvm_stdstring_cstring(u8 *stdstring, u8 *cstring) {
+
+  __cmplog_rtn_hook(get_llvm_stdstring(stdstring), cstring);
+
+}
+
+void __cmplog_rtn_llvm_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) {
+
+  __cmplog_rtn_hook(get_llvm_stdstring(stdstring1),
+                    get_llvm_stdstring(stdstring2));
+
+}
+
 /* COVERAGE manipulation features */
 
 // this variable is then used in the shm setup to create an additional map