Update compiler-rt aosp/master for 3.5 (r209699) rebase.

Change-Id: I158a30186f0faea2e2400e9dfdd878db2eb40e90
diff --git a/lib/interception/CMakeLists.txt b/lib/interception/CMakeLists.txt
index 1dfdaff..cf8b3b4 100644
--- a/lib/interception/CMakeLists.txt
+++ b/lib/interception/CMakeLists.txt
@@ -10,6 +10,7 @@
 include_directories(..)
 
 set(INTERCEPTION_CFLAGS ${SANITIZER_COMMON_CFLAGS})
+append_no_rtti_flag(INTERCEPTION_CFLAGS)
 
 if(APPLE)
   # Build universal binary on APPLE.
diff --git a/lib/interception/interception.h b/lib/interception/interception.h
index baddd6c..ac982f7 100644
--- a/lib/interception/interception.h
+++ b/lib/interception/interception.h
@@ -15,7 +15,8 @@
 #ifndef INTERCEPTION_H
 #define INTERCEPTION_H
 
-#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32)
+#if !defined(__linux__) && !defined(__FreeBSD__) && \
+  !defined(__APPLE__) && !defined(_WIN32)
 # error "Interception doesn't work on this operating system."
 #endif
 
@@ -126,9 +127,9 @@
 #  define WRAPPER_NAME(x) #x
 #  define INTERCEPTOR_ATTRIBUTE
 # else  // Static CRT
-#  define WRAP(x) wrap_##x
-#  define WRAPPER_NAME(x) "wrap_"#x
-#  define INTERCEPTOR_ATTRIBUTE
+#  define WRAP(x) __asan_wrap_##x
+#  define WRAPPER_NAME(x) "__asan_wrap_"#x
+#  define INTERCEPTOR_ATTRIBUTE __declspec(dllexport)
 # endif
 # define DECLARE_WRAPPER(ret_type, func, ...) \
     extern "C" ret_type func(__VA_ARGS__);
@@ -235,11 +236,11 @@
 
 #define INCLUDED_FROM_INTERCEPTION_LIB
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__FreeBSD__)
 # include "interception_linux.h"
-# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX(func)
+# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
 # define INTERCEPT_FUNCTION_VER(func, symver) \
-    INTERCEPT_FUNCTION_VER_LINUX(func, symver)
+    INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver)
 #elif defined(__APPLE__)
 # include "interception_mac.h"
 # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func)
diff --git a/lib/interception/interception_linux.cc b/lib/interception/interception_linux.cc
index 53f4288..6e908ac 100644
--- a/lib/interception/interception_linux.cc
+++ b/lib/interception/interception_linux.cc
@@ -12,10 +12,10 @@
 // Linux-specific interception methods.
 //===----------------------------------------------------------------------===//
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
 #include "interception.h"
 
-#include <dlfcn.h>   // for dlsym
+#include <dlfcn.h>   // for dlsym() and dlvsym()
 
 namespace __interception {
 bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
@@ -33,4 +33,4 @@
 }  // namespace __interception
 
 
-#endif  // __linux__
+#endif  // __linux__ || __FreeBSD__
diff --git a/lib/interception/interception_linux.h b/lib/interception/interception_linux.h
index cea9573..d3f774b 100644
--- a/lib/interception/interception_linux.h
+++ b/lib/interception/interception_linux.h
@@ -12,7 +12,7 @@
 // Linux-specific interception methods.
 //===----------------------------------------------------------------------===//
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
 
 #if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
 # error "interception_linux.h should be included from interception library only"
@@ -28,20 +28,20 @@
 void *GetFuncAddrVer(const char *func_name, const char *ver);
 }  // namespace __interception
 
-#define INTERCEPT_FUNCTION_LINUX(func) \
-    ::__interception::GetRealFunctionAddress( \
-          #func, (::__interception::uptr*)&REAL(func), \
-          (::__interception::uptr)&(func), \
-          (::__interception::uptr)&WRAP(func))
+#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)                          \
+  ::__interception::GetRealFunctionAddress(                                \
+      #func, (::__interception::uptr *)&__interception::PTR_TO_REAL(func), \
+      (::__interception::uptr) & (func),                                   \
+      (::__interception::uptr) & WRAP(func))
 
 #if !defined(__ANDROID__)  // android does not have dlvsym
-# define INTERCEPT_FUNCTION_VER_LINUX(func, symver) \
+# define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
      ::__interception::real_##func = (func##_f)(unsigned long) \
          ::__interception::GetFuncAddrVer(#func, symver)
 #else
-# define INTERCEPT_FUNCTION_VER_LINUX(func, symver) \
-     INTERCEPT_FUNCTION_LINUX(func)
+# define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
+     INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
 #endif  // !defined(__ANDROID__)
 
 #endif  // INTERCEPTION_LINUX_H
-#endif  // __linux__
+#endif  // __linux__ || __FreeBSD__
diff --git a/lib/interception/interception_type_test.cc b/lib/interception/interception_type_test.cc
index 7b79b78..98ce2e6 100644
--- a/lib/interception/interception_type_test.cc
+++ b/lib/interception/interception_type_test.cc
@@ -19,13 +19,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
-COMPILER_CHECK(sizeof(SIZE_T) == sizeof(size_t));
-COMPILER_CHECK(sizeof(SSIZE_T) == sizeof(ssize_t));
-COMPILER_CHECK(sizeof(PTRDIFF_T) == sizeof(ptrdiff_t));
-COMPILER_CHECK(sizeof(INTMAX_T) == sizeof(intmax_t));
+COMPILER_CHECK(sizeof(::SIZE_T) == sizeof(size_t));
+COMPILER_CHECK(sizeof(::SSIZE_T) == sizeof(ssize_t));
+COMPILER_CHECK(sizeof(::PTRDIFF_T) == sizeof(ptrdiff_t));
+COMPILER_CHECK(sizeof(::INTMAX_T) == sizeof(intmax_t));
 
 #ifndef __APPLE__
-COMPILER_CHECK(sizeof(OFF64_T) == sizeof(off64_t));
+COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t));
 #endif
 
 // The following are the cases when pread (and friends) is used instead of
@@ -33,7 +33,7 @@
 // rest (they depend on _FILE_OFFSET_BITS setting when building an application).
 # if defined(__ANDROID__) || !defined _FILE_OFFSET_BITS || \
   _FILE_OFFSET_BITS != 64
-COMPILER_CHECK(sizeof(OFF_T) == sizeof(off_t));
+COMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t));
 # endif
 
 #endif
diff --git a/lib/interception/interception_win.cc b/lib/interception/interception_win.cc
index abbab24..332fc71 100644
--- a/lib/interception/interception_win.cc
+++ b/lib/interception/interception_win.cc
@@ -56,91 +56,136 @@
   *(ptrdiff_t*)(jmp_from + 1) = offset;
 }
 
-bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) {
-#ifdef _WIN64
-# error OverrideFunction was not tested on x64
-#endif
-  // Basic idea:
-  // We write 5 bytes (jmp-to-new_func) at the beginning of the 'old_func'
-  // to override it. We want to be able to execute the original 'old_func' from
-  // the wrapper, so we need to keep the leading 5+ bytes ('head') of the
-  // original instructions somewhere with a "jmp old_func+head".
-  // We call these 'head'+5 bytes of instructions a "trampoline".
-
+static char *GetMemoryForTrampoline(size_t size) {
   // Trampolines are allocated from a common pool.
   const int POOL_SIZE = 1024;
   static char *pool = NULL;
   static size_t pool_used = 0;
-  if (pool == NULL) {
-    pool = (char*)VirtualAlloc(NULL, POOL_SIZE,
-                               MEM_RESERVE | MEM_COMMIT,
-                               PAGE_EXECUTE_READWRITE);
-    // FIXME: set PAGE_EXECUTE_READ access after setting all interceptors?
-    if (pool == NULL)
-      return false;
+  if (!pool) {
+    pool = (char *)VirtualAlloc(NULL, POOL_SIZE, MEM_RESERVE | MEM_COMMIT,
+                                PAGE_EXECUTE_READWRITE);
+    // FIXME: Might want to apply PAGE_EXECUTE_READ access after all the
+    // interceptors are in place.
+    if (!pool)
+      return NULL;
     _memset(pool, 0xCC /* int 3 */, POOL_SIZE);
   }
 
-  char* old_bytes = (char*)old_func;
-  char* trampoline = pool + pool_used;
+  if (pool_used + size > POOL_SIZE)
+    return NULL;
 
-  // Find out the number of bytes of the instructions we need to copy to the
-  // island and store it in 'head'.
-  size_t head = 0;
-  while (head < 5) {
-    switch (old_bytes[head]) {
+  char *ret = pool + pool_used;
+  pool_used += size;
+  return ret;
+}
+
+// Returns 0 on error.
+static size_t RoundUpToInstrBoundary(size_t size, char *code) {
+  size_t cursor = 0;
+  while (cursor < size) {
+    switch (code[cursor]) {
+      case '\x51':  // push ecx
+      case '\x52':  // push edx
+      case '\x53':  // push ebx
+      case '\x54':  // push esp
       case '\x55':  // push ebp
       case '\x56':  // push esi
       case '\x57':  // push edi
-        head++;
+      case '\x5D':  // pop ebp
+        cursor++;
+        continue;
+      case '\x6A':  // 6A XX = push XX
+        cursor += 2;
+        continue;
+      case '\xE9':  // E9 XX YY ZZ WW = jmp WWZZYYXX
+        cursor += 5;
         continue;
     }
-    switch (*(unsigned short*)(old_bytes + head)) {  // NOLINT
+    switch (*(unsigned short*)(code + cursor)) {  // NOLINT
       case 0xFF8B:  // 8B FF = mov edi, edi
       case 0xEC8B:  // 8B EC = mov ebp, esp
       case 0xC033:  // 33 C0 = xor eax, eax
-        head += 2;
+        cursor += 2;
         continue;
+      case 0x458B:  // 8B 45 XX = mov eax, dword ptr [ebp+XXh]
+      case 0x5D8B:  // 8B 5D XX = mov ebx, dword ptr [ebp+XXh]
       case 0xEC83:  // 83 EC XX = sub esp, XX
-        head += 3;
+        cursor += 3;
         continue;
       case 0xC1F7:  // F7 C1 XX YY ZZ WW = test ecx, WWZZYYXX
-        head += 6;
+        cursor += 6;
+        continue;
+      case 0x3D83:  // 83 3D XX YY ZZ WW TT = cmp TT, WWZZYYXX
+        cursor += 7;
         continue;
     }
-    switch (0x00FFFFFF & *(unsigned int*)(old_bytes + head)) {
+    switch (0x00FFFFFF & *(unsigned int*)(code + cursor)) {
       case 0x24448A:  // 8A 44 24 XX = mov eal, dword ptr [esp+XXh]
       case 0x244C8B:  // 8B 4C 24 XX = mov ecx, dword ptr [esp+XXh]
       case 0x24548B:  // 8B 54 24 XX = mov edx, dword ptr [esp+XXh]
+      case 0x24748B:  // 8B 74 24 XX = mov esi, dword ptr [esp+XXh]
       case 0x247C8B:  // 8B 7C 24 XX = mov edi, dword ptr [esp+XXh]
-        head += 4;
+        cursor += 4;
         continue;
     }
 
     // Unknown instruction!
-    return false;
+    // FIXME: Unknown instruction failures might happen when we add a new
+    // interceptor or a new compiler version. In either case, they should result
+    // in visible and readable error messages. However, merely calling abort()
+    // or __debugbreak() leads to an infinite recursion in CheckFailed.
+    // Do we have a good way to abort with an error message here?
+    return 0;
   }
 
-  if (pool_used + head + 5 > POOL_SIZE)
-    return false;
+  return cursor;
+}
 
-  // Now put the "jump to trampoline" instruction into the original code.
+bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) {
+#ifdef _WIN64
+#error OverrideFunction is not yet supported on x64
+#endif
+  // Function overriding works basically like this:
+  // We write "jmp <new_func>" (5 bytes) at the beginning of the 'old_func'
+  // to override it.
+  // We might want to be able to execute the original 'old_func' from the
+  // wrapper, in this case we need to keep the leading 5+ bytes ('head')
+  // of the original code somewhere with a "jmp <old_func+head>".
+  // We call these 'head'+5 bytes of instructions a "trampoline".
+  char *old_bytes = (char *)old_func;
+
+  // We'll need at least 5 bytes for a 'jmp'.
+  size_t head = 5;
+  if (orig_old_func) {
+    // Find out the number of bytes of the instructions we need to copy
+    // to the trampoline and store it in 'head'.
+    head = RoundUpToInstrBoundary(head, old_bytes);
+    if (!head)
+      return false;
+
+    // Put the needed instructions into the trampoline bytes.
+    char *trampoline = GetMemoryForTrampoline(head + 5);
+    if (!trampoline)
+      return false;
+    _memcpy(trampoline, old_bytes, head);
+    WriteJumpInstruction(trampoline + head, old_bytes + head);
+    *orig_old_func = (uptr)trampoline;
+  }
+
+  // Now put the "jmp <new_func>" instruction at the original code location.
+  // We should preserve the EXECUTE flag as some of our own code might be
+  // located in the same page (sic!).  FIXME: might consider putting the
+  // __interception code into a separate section or something?
   DWORD old_prot, unused_prot;
-  if (!VirtualProtect((void*)old_func, head, PAGE_EXECUTE_READWRITE,
+  if (!VirtualProtect((void *)old_bytes, head, PAGE_EXECUTE_READWRITE,
                       &old_prot))
     return false;
 
-  // Put the needed instructions into the trampoline bytes.
-  _memcpy(trampoline, old_bytes, head);
-  WriteJumpInstruction(trampoline + head, old_bytes + head);
-  *orig_old_func = (uptr)trampoline;
-  pool_used += head + 5;
-
-  // Intercept the 'old_func'.
-  WriteJumpInstruction(old_bytes, (char*)new_func);
+  WriteJumpInstruction(old_bytes, (char *)new_func);
   _memset(old_bytes + 5, 0xCC /* int 3 */, head - 5);
 
-  if (!VirtualProtect((void*)old_func, head, old_prot, &unused_prot))
+  // Restore the original permissions.
+  if (!VirtualProtect((void *)old_bytes, head, old_prot, &unused_prot))
     return false;  // not clear if this failure bothers us.
 
   return true;