Merge "Add attribute weak on operator new/delete."
diff --git a/build/core/ndk-common.sh b/build/core/ndk-common.sh
index 1048053..974f934 100644
--- a/build/core/ndk-common.sh
+++ b/build/core/ndk-common.sh
@@ -270,8 +270,10 @@
     # "uname -m" reports i386 on Snow Leopard even though its architecture is
     # 64-bit. In order to use it to build 64-bit toolchains we need to fix the
     # reporting anomoly here.
-    if [ "$HOST_OS" = darwin -a "`uname -r`" = 10.8.0 ] ; then
-      HOST_ARCH=x86_64
+    if [ "$HOST_OS" = darwin ] ; then
+        if ! echo __LP64__ | (CCOPTS= gcc -E - 2>/dev/null) | grep -q __LP64__ ; then
+            HOST_ARCH=x86_64
+        fi
     fi
     ;;
     amd64) HOST_ARCH=x86_64
diff --git a/build/tools/make-standalone-toolchain.sh b/build/tools/make-standalone-toolchain.sh
index 7df78e9..d96cf36 100755
--- a/build/tools/make-standalone-toolchain.sh
+++ b/build/tools/make-standalone-toolchain.sh
@@ -180,7 +180,7 @@
 # Get GCC_BASE_VERSION.  Note that GCC_BASE_VERSION may be slightly different from GCC_VERSION.
 # eg. In gcc4.6 GCC_BASE_VERSION is "4.6.x-google"
 LIBGCC_PATH=`$TOOLCHAIN_GCC -print-libgcc-file-name`
-LIBGCC_BASE_PATH=${LIBGCC_PATH%/libgcc.a}  # base path of libgcc.a
+LIBGCC_BASE_PATH=${LIBGCC_PATH%/*}         # base path of libgcc.a
 GCC_BASE_VERSION=${LIBGCC_BASE_PATH##*/}   # stuff after the last /
 
 # Create temporary directory
@@ -194,9 +194,9 @@
   # Copy the clang/llvm toolchain prebuilt binaries
   run copy_directory "$LLVM_TOOLCHAIN_PATH" "$TMPDIR"
 
-  # Move clang and clang++ to clang-LLVM_VERSION/++, then create scripts
-  # linking them with predefined -target flag.  This is to make clang/++
-  # easier drop-in replacement for gcc/++ in NDK standalone mode.
+  # Move clang and clang++ to clang${LLVM_VERSION} and clang${LLVM_VERSION}++,
+  # then create scripts linking them with predefined -target flag.  This is to
+  # make clang/++ easier drop-in replacement for gcc/++ in NDK standalone mode.
   # Note that the file name of "clang" isn't important, and the trailing
   # "++" tells clang to compile in C++ mode
   LLVM_TARGET=
@@ -218,9 +218,15 @@
   # otherwise clang3.1++ may still compile *.c code as C, not C++, which
   # is not consistent with g++
   LLVM_VERSION_WITHOUT_DOT=$(echo "$LLVM_VERSION" | sed -e "s!\.!!")
-  mv "$TMPDIR/bin/clang" "$TMPDIR/bin/clang$LLVM_VERSION_WITHOUT_DOT"
-  rm "$TMPDIR/bin/clang++"
-  ln -s "clang$LLVM_VERSION_WITHOUT_DOT" "$TMPDIR/bin/clang$LLVM_VERSION_WITHOUT_DOT++"
+  mv "$TMPDIR/bin/clang${HOST_EXE}" "$TMPDIR/bin/clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE}"
+  if [ -h "$TMPDIR/bin/clang++${HOST_EXE}" ] ; then
+    ## clang++ is a link to clang.  Remove it and reconstruct
+    rm "$TMPDIR/bin/clang++${HOST_EXE}"
+    ln -s "clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE}" "$TMPDIR/bin/clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE}"
+  else
+    mv "$TMPDIR/bin/clang++${HOST_EXE}" "$TMPDIR/bin/clang$LLVM_VERSION_WITHOUT_DOT++${HOST_EXE}"
+  fi
+
   cat > "$TMPDIR/bin/clang" <<EOF
 \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT -target $LLVM_TARGET "\$@"
 EOF
@@ -228,6 +234,15 @@
 \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT++ -target $LLVM_TARGET "\$@"
 EOF
   chmod 0755 "$TMPDIR/bin/clang" "$TMPDIR/bin/clang++"
+
+  if [ -n "$HOST_EXE" ] ; then
+    cat > "$TMPDIR/bin/clang.cmd" <<EOF
+%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE} -target $LLVM_TARGET %*
+EOF
+    cat > "$TMPDIR/bin/clang++.cmd" <<EOF
+%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE} -target $LLVM_TARGET %*
+EOF
+  fi
 fi
 
 dump "Copying sysroot headers and libraries..."
diff --git a/build/tools/prebuilt-common.sh b/build/tools/prebuilt-common.sh
index 8577279..b5ff14e 100644
--- a/build/tools/prebuilt-common.sh
+++ b/build/tools/prebuilt-common.sh
@@ -728,17 +728,19 @@
     # We only do this if the CC variable is not defined to a given value
     # and the --mingw or --try-64 options are not used.
     #
-    if [ "$HOST_OS" = "linux" -a -z "$CC" -a "$MINGW" != "yes" ]; then
-        if [ "$TRY64" != "yes" ]; then
-            LEGACY_PREFIX=i686
-        else
-            LEGACY_PREFIX=x86_64
+    if [ -z "$CC" -a "$MINGW" != "yes" ]; then
+        LEGACY_TOOLCHAIN_DIR=
+        if [ "$HOST_OS" = "linux" ]; then
+            LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/tools/gcc-sdk"
+            LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/"
+        elif [ "$HOST_OS" = "darwin" ]; then
+            LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1/bin"
+            LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/i686-apple-darwin10-"
         fi
-        LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/tools/gcc-sdk"
         if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then
-            log "Forcing generation of Linux binaries with legacy $LEGACY_PREFIX toolchain"
-            CC="$LEGACY_TOOLCHAIN_DIR/gcc"
-            CXX="$LEGACY_TOOLCHAIN_DIR/g++"
+            log "Forcing generation of $HOST_OS binaries with legacy toolchain"
+            CC="${LEGACY_TOOLCHAIN_PREFIX}gcc"
+            CXX="${LEGACY_TOOLCHAIN_PREFIX}g++"
         fi
     fi
 
@@ -748,11 +750,7 @@
     STRIP=${STRIP:-strip}
     case $HOST_TAG in
         darwin-*)
-            # Try to build with Tiger SDK if available
-            if check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku 10.4; then
-                log "Generating Tiger-compatible binaries!"
-            # Otherwise with Leopard SDK
-            elif check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk 10.5; then
+            if check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk 10.5; then
                 log "Generating Leopard-compatible binaries!"
             else
                 local version=`sw_vers -productVersion`
@@ -777,7 +775,6 @@
     int test_array[1-2*(sizeof(void*) != 4)];
 EOF
     log_n "Checking whether the compiler generates 32-bit binaries..."
-    HOST_BITS=32
     log2 $CC $HOST_CFLAGS -c -o $TMPO $TMPC
     $NDK_CCACHE $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1
     if [ $? != 0 ] ; then
@@ -788,15 +785,18 @@
             #        will not work well with the GCC toolchain scripts.
             CC="$CC -m32"
             CXX="$CXX -m32"
-        else
-            HOST_BITS=64
         fi
     else
         log "yes"
+        if [ "$TRY64" = "yes" ]; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        fi
     fi
 
-    # For now, we only support building 32-bit binaries anyway
-    if [ "$TRY64" != "yes" ]; then
+    if [ "$TRY64" = "yes" ]; then
+        HOST_BITS=64
+    else
         force_32bit_binaries  # to modify HOST_TAG and others
         HOST_BITS=32
     fi
diff --git a/sources/android/cpufeatures/cpu-features.c b/sources/android/cpufeatures/cpu-features.c
index 2eb417f..02ea74f 100644
--- a/sources/android/cpufeatures/cpu-features.c
+++ b/sources/android/cpufeatures/cpu-features.c
@@ -28,7 +28,7 @@
 
 /* ChangeLog for this library:
  *
- * NDK r??: Add new ARM CPU features: VFPv2, VFP_D32, VFP_FP16,
+ * NDK r8c: Add new ARM CPU features: VFPv2, VFP_D32, VFP_FP16,
  *          VFP_FMA, NEON_FMA, IDIV_ARM, IDIV_THUMB2 and iWMMXt.
  *
  *          Rewrite the code to parse /proc/self/auxv instead of
@@ -96,7 +96,7 @@
     __asm__ __volatile__ ( \
       "push %%ebx\n"
       "cpuid\n" \
-      "mov %1, %%ebx\n"
+      "mov %%ebx, %1\n"
       "pop %%ebx\n"
       : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
       : "a" (func) \
diff --git a/sources/cxx-stl/gabi++/Android.mk b/sources/cxx-stl/gabi++/Android.mk
index 09333dc..a868e0d 100644
--- a/sources/cxx-stl/gabi++/Android.mk
+++ b/sources/cxx-stl/gabi++/Android.mk
@@ -8,14 +8,14 @@
   LOCAL_MODULE:= gabi++_shared
   LOCAL_SRC_FILES:= libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).so
   LOCAL_EXPORT_C_INCLUDES := $(libgabi++_c_includes)
-  LOCAL_CPP_FEATURES := rtti
+  LOCAL_CPP_FEATURES := rtti exceptions
   include $(PREBUILT_SHARED_LIBRARY)
 
   include $(CLEAR_VARS)
   LOCAL_MODULE:= gabi++_static
   LOCAL_SRC_FILES:= libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).a
   LOCAL_EXPORT_C_INCLUDES := $(libgabi++_c_includes)
-  LOCAL_CPP_FEATURES := rtti
+  LOCAL_CPP_FEATURES := rtti exceptions
   include $(PREBUILT_STATIC_LIBRARY)
 
 else # ! GABIXX_FORCE_REBUILD
@@ -30,7 +30,7 @@
   LOCAL_SRC_FILES:= $(libgabi++_src_files)
   LOCAL_EXPORT_C_INCLUDES := $(libgabi++_c_includes)
   LOCAL_C_INCLUDES := $(libgabi++_c_includes)
-  LOCAL_CPP_FEATURES := rtti
+  LOCAL_CPP_FEATURES := rtti exceptions
   include $(BUILD_SHARED_LIBRARY)
 
   # And now the static version
@@ -41,7 +41,7 @@
   LOCAL_CPP_EXTENSION := .cc
   LOCAL_EXPORT_C_INCLUDES := $(libgabi++_c_includes)
   LOCAL_C_INCLUDES := $(libgabi++_c_includes)
-  LOCAL_CPP_FEATURES := rtti
+  LOCAL_CPP_FEATURES := rtti exceptions
   include $(BUILD_STATIC_LIBRARY)
 
 endif # ! GABIXX_FORCE_REBUILD
diff --git a/sources/cxx-stl/gabi++/src/cxxabi.cc b/sources/cxx-stl/gabi++/src/cxxabi.cc
index 782553c..60d1884 100644
--- a/sources/cxx-stl/gabi++/src/cxxabi.cc
+++ b/sources/cxx-stl/gabi++/src/cxxabi.cc
@@ -30,6 +30,8 @@
 #include <cstdlib>
 #include <cxxabi.h>
 #include <exception>
+#include <pthread.h>
+
 #include "helper_func_internal.h"
 
 namespace {
@@ -45,14 +47,69 @@
     __cxa_free_exception(exc);
   }
 
-  __cxa_thread_info* getThreadInfo() {
-    // Only single thread for now
-    static __cxa_thread_info info;
-    return &info;
-  }
+  // Technical note:
+  // Use a pthread_key_t to hold the key used to store our thread-specific
+  // __cxa_thread_info objects. The key is created and destroyed through
+  // a static C++ object.
+  //
+
+  // Due to a bug in the dynamic linker that was only fixed in Froyo, the
+  // static C++ destructor may be called with a value of NULL for the
+  // 'this' pointer. As such, any attempt to access any field in the
+  // object there will result in a crash. To work-around this, store
+  // the key object as a 'static' variable outside of the C++ object.
+  static pthread_key_t __cxa_thread_key;
+
+  class CxaThreadKey {
+  public:
+    // Called at program initialization time, or when the shared library
+    // is loaded through dlopen().
+    CxaThreadKey() {
+      if (pthread_key_create(&__cxa_thread_key, freeObject) != 0) {
+        fatalError("Can't allocate C++ runtime pthread_key_t");
+      }
+    }
+
+    // Called at program exit time, or when the shared library is
+    // unloaded through dlclose(). See note above.
+    ~CxaThreadKey() {
+      pthread_key_delete(__cxa_thread_key);
+    }
+
+    static __cxa_thread_info* getFast() {
+      void* obj = pthread_getspecific(__cxa_thread_key);
+      return reinterpret_cast<__cxa_thread_info*>(obj);
+    }
+
+    static __cxa_thread_info* getSlow() {
+      void* obj = pthread_getspecific(__cxa_thread_key);
+      if (obj == NULL) {
+        obj = malloc(sizeof(__cxa_thread_info));
+        if (!obj) {
+          // Shouldn't happen, but better be safe than sorry.
+          fatalError("Can't allocate thread-specific C++ runtime info block.");
+        }
+        memset(obj, 0, sizeof(__cxa_thread_info));
+        pthread_setspecific(__cxa_thread_key, obj);
+      }
+      return reinterpret_cast<__cxa_thread_info*>(obj);
+    }
+
+  private:
+    // Called when a thread is destroyed.
+    static void freeObject(void* obj) {
+      free(obj);
+    }
+
+  };
+
+  // The single static instance, this forces the compiler to register
+  // a constructor and destructor for this object in the final library
+  // file. They handle the pthread_key_t allocation/deallocation.
+  static CxaThreadKey instance;
 
   void throwException(__cxa_exception *header) {
-    __cxa_thread_info *info = getThreadInfo();
+    __cxa_thread_info *info = CxaThreadKey::getSlow();
     header->unexpectedHandler = info->unexpectedHandler;
     if (!header->unexpectedHandler) {
       header->unexpectedHandler = std::current_unexpected_fn;
@@ -75,17 +132,17 @@
 namespace __cxxabiv1 {
 
   extern "C" void __cxa_pure_virtual() {
-    fprintf(stderr, "Pure virtual function called. Terminate!\n");
-    std::terminate();
+    fatalError("Pure virtual function called!");
   }
 
   extern "C" __cxa_eh_globals* __cxa_get_globals() {
-    return &getThreadInfo()->globals;
+    __cxa_thread_info* info = CxaThreadKey::getSlow();
+    return &info->globals;
   }
 
   extern "C" __cxa_eh_globals* __cxa_get_globals_fast() {
-    // TODO: Implement a fast version
-    return __cxa_get_globals();
+    __cxa_thread_info* info = CxaThreadKey::getFast();
+    return &info->globals;
   }
 
 
@@ -96,8 +153,7 @@
       // Since Android uses memory-overcommit, we enter here only when
       // the exception object is VERY large. This will propably never happen.
       // Therefore, we decide to use no emergency spaces.
-      // Thank David Turner's advice!
-      std::terminate();
+      fatalError("Not enough memory to allocate exception!");
     }
 
     memset(buffer, 0, sizeof(__cxa_exception));
@@ -111,7 +167,7 @@
       try {
         exc->exceptionDestructor(thrown_exception);
       } catch (...) {
-        std::terminate(); // Failed when exception destructing
+        fatalError("Exception destructor has thrown!");
       }
     }
 
@@ -137,8 +193,7 @@
     __cxa_exception* header = globals->caughtExceptions;
     _Unwind_Exception* exception = &header->unwindHeader;
     if (!header) {
-      fprintf(stderr, "Attempting to rethrow an exception that doesn't exist!\n");
-      std::terminate();
+      fatalError("Attempting to rethrow an exception that doesn't exist!");
     }
 
     if (isOurCxxException(exception->exception_class)) {
@@ -158,7 +213,7 @@
 
     if (!isOurCxxException(exception->exception_class)) {
       if (globals->caughtExceptions) {
-        std::terminate();
+        fatalError("Can't handle non-C++ exception!");
       }
     }
 
@@ -200,7 +255,7 @@
       __cxa_free_exception(header+1);
       return;
     } else if (count < 0) {
-      std::terminate(); // Some bug happens here
+      fatalError("Internal error during exception handling!");
     }
 
     header->handlerCount = count;
diff --git a/sources/cxx-stl/gabi++/src/helper_func_internal.cc b/sources/cxx-stl/gabi++/src/helper_func_internal.cc
index c4f92b0..8425327 100644
--- a/sources/cxx-stl/gabi++/src/helper_func_internal.cc
+++ b/sources/cxx-stl/gabi++/src/helper_func_internal.cc
@@ -42,6 +42,10 @@
 #include <unwind.h>
 #include "helper_func_internal.h"
 
+#include <android/log.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
 namespace __cxxabiv1 {
 
   void call_terminate(_Unwind_Exception* unwind_exception) {
@@ -500,4 +504,46 @@
 
 #endif // __arm__
 
+  void fatalError(const char* message) {
+
+    // Note: Printing to stderr is only useful when running an executable
+    // from a shell, e.g. when using 'adb shell'. For regular
+    // applications, stderr is redirected to /dev/null by default.
+    fprintf(stderr, "PANIC:GAbi++:%s\n", message);
+
+    // Always print the message to the log, when possible. Use
+    // dlopen()/dlsym() to avoid adding an explicit dependency
+    // to -llog in GAbi++ for this sole feature.
+    //
+    // An explicit dependency to -ldl can be avoided because these
+    // functions are implemented directly by the dynamic linker.
+    // That is, except when this code is linked into a static
+    // executable. In this case, adding -ldl to the final link command
+    // will be necessary, but the dlopen() will always return NULL.
+    //
+    // There is unfortunately no way to detect where this code is going
+    // to be used at compile time, but static executables are strongly
+    // discouraged on the platform because they can't implement ASLR.
+    //
+    typedef void (*logfunc_t)(int, const char*, const char*);
+    logfunc_t logger = NULL;
+
+    // Note that this should always succeed in a regular application,
+    // because the library is already loaded into the process' address
+    // space by Zygote before forking the application process.
+    // This will fail in static executables, because the static
+    // version of -ldl only contains empty stubs.
+    void* liblog = dlopen("liblog.so", RTLD_NOW);
+
+    if (liblog != NULL) {
+      logger = reinterpret_cast<logfunc_t>(dlsym(liblog, "__android_log_print"));
+      if (logger != NULL) {
+        (*logger)(ANDROID_LOG_FATAL, "GAbi++", message);
+      }
+      dlclose(liblog);
+    }
+
+    std::terminate();
+  }
+
 } // namespace __cxxabiv1
diff --git a/sources/cxx-stl/gabi++/src/helper_func_internal.h b/sources/cxx-stl/gabi++/src/helper_func_internal.h
index 1eb5c72..2b0a189 100644
--- a/sources/cxx-stl/gabi++/src/helper_func_internal.h
+++ b/sources/cxx-stl/gabi++/src/helper_func_internal.h
@@ -119,6 +119,10 @@
                            _Unwind_Exception* unwind_exception, _Unwind_Context* context) {
 #endif
 
+  // Print an error message to either stderr or the log. Then calls
+  // std::terminate(). Note: This always appends a newline to the message.
+  void fatalError(const char* message);
+
 } // namespace __cxxabiv1
 
 #endif // __GXXABI_HELPER_FUNC_INTERNAL_H
diff --git a/sources/cxx-stl/gabi++/src/terminate.cc b/sources/cxx-stl/gabi++/src/terminate.cc
index 620d643..576b18a 100644
--- a/sources/cxx-stl/gabi++/src/terminate.cc
+++ b/sources/cxx-stl/gabi++/src/terminate.cc
@@ -30,7 +30,36 @@
 #include <exception>
 
 namespace std {
-  terminate_handler default_terminate_fn = abort;
+
+  // The default std::terminate() implementation will crash the process.
+  // This is done to help debugging, i.e.:
+  //   - When running the program in a debugger, it's trivial to get
+  //     a complete stack trace explaining the failure.
+  //
+  //   - Otherwise, the default SIGSEGV handler will generate a stack
+  //     trace in the log, that can later be processed with ndk-stack
+  //     and other tools.
+  //
+  //   - Finally, this also works when a custom SIGSEGV handler has been
+  //     installed. E.g. when using Google Breakpad, the termination will
+  //     be recorded in a Minidump, which contains a stack trace to be
+  //     later analyzed.
+  //
+  // The C++ specification states that the default std::terminate()
+  // handler is library-specific, even though most implementation simply
+  // choose to call abort() in this case.
+  //
+  static void default_terminate(void) {
+    // The crash address is just a "magic" constant that can be used to
+    // identify stack traces (like 0xdeadbaad is used when heap corruption
+    // is detected in the C library). 'cab1' stands for "C++ ABI" :-)
+    *(reinterpret_cast<char*>(0xdeadcab1)) = 0;
+
+    // should not be here, but just in case.
+    abort();
+  }
+
+  terminate_handler default_terminate_fn = default_terminate;
   terminate_handler current_terminate_fn = default_terminate_fn;
 
   unexpected_handler default_unexpected_fn = terminate;
diff --git a/tests/build/issue39824-__BYTE_ORDER/BROKEN_BUILD b/tests/build/issue39824-__BYTE_ORDER/BROKEN_BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/build/issue39824-__BYTE_ORDER/BROKEN_BUILD
diff --git a/tests/build/issue39824-__BYTE_ORDER/jni/Android.mk b/tests/build/issue39824-__BYTE_ORDER/jni/Android.mk
new file mode 100644
index 0000000..9bd21ad
--- /dev/null
+++ b/tests/build/issue39824-__BYTE_ORDER/jni/Android.mk
@@ -0,0 +1,7 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := issue39824-__BYTE_ORDER
+LOCAL_SRC_FILES := issue39824-__BYTE_ORDER.c
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/build/issue39824-__BYTE_ORDER/jni/Application.mk b/tests/build/issue39824-__BYTE_ORDER/jni/Application.mk
new file mode 100644
index 0000000..a252a72
--- /dev/null
+++ b/tests/build/issue39824-__BYTE_ORDER/jni/Application.mk
@@ -0,0 +1 @@
+APP_ABI := all
diff --git a/tests/build/issue39824-__BYTE_ORDER/jni/issue39824-__BYTE_ORDER.c b/tests/build/issue39824-__BYTE_ORDER/jni/issue39824-__BYTE_ORDER.c
new file mode 100644
index 0000000..06e9cdb
--- /dev/null
+++ b/tests/build/issue39824-__BYTE_ORDER/jni/issue39824-__BYTE_ORDER.c
@@ -0,0 +1,6 @@
+#include <sys/endian.h>
+
+int main()
+{
+  return 0 * __BYTE_ORDER;
+}
diff --git a/tests/build/issue39983-PAGE_SIZE/jni/Android.mk b/tests/build/issue39983-PAGE_SIZE/jni/Android.mk
new file mode 100644
index 0000000..712f588
--- /dev/null
+++ b/tests/build/issue39983-PAGE_SIZE/jni/Android.mk
@@ -0,0 +1,7 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := issue39983-PAGE_SIZE
+LOCAL_SRC_FILES := issue39983-PAGE_SIZE.c
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/build/issue39983-PAGE_SIZE/jni/Application.mk b/tests/build/issue39983-PAGE_SIZE/jni/Application.mk
new file mode 100644
index 0000000..a252a72
--- /dev/null
+++ b/tests/build/issue39983-PAGE_SIZE/jni/Application.mk
@@ -0,0 +1 @@
+APP_ABI := all
diff --git a/tests/build/issue39983-PAGE_SIZE/jni/issue39983-PAGE_SIZE.c b/tests/build/issue39983-PAGE_SIZE/jni/issue39983-PAGE_SIZE.c
new file mode 100644
index 0000000..65de46e
--- /dev/null
+++ b/tests/build/issue39983-PAGE_SIZE/jni/issue39983-PAGE_SIZE.c
@@ -0,0 +1,6 @@
+#include <pthread.h>
+
+int main()
+{
+    return 0 * PTHREAD_STACK_MIN;
+}
diff --git a/tests/build/topological-sort/BROKEN_BUILD b/tests/build/topological-sort/BROKEN_BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/build/topological-sort/BROKEN_BUILD
diff --git a/tests/device/test-gabi++/README b/tests/device/test-gabi++/README
index 720c031..cd4251a 100644
--- a/tests/device/test-gabi++/README
+++ b/tests/device/test-gabi++/README
@@ -1,7 +1,7 @@
-This test is meant to test the GABI++ library which provides, at the
-moment, basic RTTI support withtout using the GNU libsupc++.a
+This test is meant to test the GABI++ library which provides C++
+RTTI and exceptions support without using the GNU libsupc++.a
 
 This is really a way to check that the C++ compiler properly links against
 libgabi++_static and libgabi++_shared without any kind of conflict, and that
-the dynamic_cast<> really works.
+dynamic_cast<> and try..throw..catch really work.
 
diff --git a/tests/device/test-gabi++/jni/Android.mk b/tests/device/test-gabi++/jni/Android.mk
index 947a407..6aea452 100644
--- a/tests/device/test-gabi++/jni/Android.mk
+++ b/tests/device/test-gabi++/jni/Android.mk
@@ -12,4 +12,16 @@
 LOCAL_SHARED_LIBRARIES := gabi++_shared
 include $(BUILD_EXECUTABLE)
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := test_gabixx_static_exceptions
+LOCAL_SRC_FILES := test_gabixx_exceptions.cpp
+LOCAL_STATIC_LIBRARIES := gabi++_static
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test_gabixx_shared_exceptions
+LOCAL_SRC_FILES := test_gabixx_exceptions.cpp
+LOCAL_SHARED_LIBRARIES := gabi++_shared
+include $(BUILD_EXECUTABLE)
+
 $(call import-module,cxx-stl/gabi++)
diff --git a/tests/device/test-gabi++/jni/test_gabixx_exceptions.cpp b/tests/device/test-gabi++/jni/test_gabixx_exceptions.cpp
new file mode 100644
index 0000000..f390589
--- /dev/null
+++ b/tests/device/test-gabi++/jni/test_gabixx_exceptions.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <cstdio>
+#include <new>
+
+int main()
+{
+    char *buf;
+    try
+    {
+        buf = new char[512];
+        throw "Memory allocation failure!";
+
+        std::fprintf(stderr,"KO: Exception *not* raised!\n");
+        return 1;
+    }
+    catch( char const* str )
+    {
+        std::printf("OK: Exception raised: %s\n", str);
+    }
+    return 0;
+}
diff --git a/tests/run-tests.sh b/tests/run-tests.sh
index 1ef1aa6..bc931bd 100755
--- a/tests/run-tests.sh
+++ b/tests/run-tests.sh
@@ -555,7 +555,7 @@
             echo "Skipping broken device test build: `basename $1`"
             return 0
         fi
-        echo "Building NDK device test: `basename $1` in $1"
+        echo "Building NDK device test: `basename $1`"
         build_project $1 "yes"
     }
 
@@ -568,6 +568,7 @@
         local DEVICE=$1
         local CPU_ABI=$2
         local TEST=$3
+        local TEST_NAME="$(basename $TEST)"
         local SRCDIR
         local DSTDIR="$4/ndk-tests"
         local SRCFILE
@@ -611,7 +612,7 @@
             fi
         done
         for PROGRAM in $PROGRAMS; do
-            dump "Running device test [$CPU_ABI]: `basename $PROGRAM`"
+            dump "Running device test [$CPU_ABI]: $TEST_NAME (`basename $PROGRAM`)"
             adb_var_shell_cmd "$DEVICE" "" LD_LIBRARY_PATH="$DSTDIR" $PROGRAM
             if [ $? != 0 ] ; then
                 dump "   ---> TEST FAILED!!"
@@ -668,12 +669,17 @@
             adb_var_shell_cmd "$DEVICE" CPU_ABI2 getprop ro.product.cpu.abi2
             CPU_ABIS="$CPU_ABI1,$CPU_ABI2"
             CPU_ABIS=$(commas_to_spaces $CPU_ABIS)
+            if [ "$CPU_ABIS" = " " ]; then
+              # Very old cupcake-based Android devices don't have these properties
+              # defined. Fortunately, they are all armeabi-based.
+              CPU_ABIS=armeabi
+            fi
             for CPU_ABI in $CPU_ABIS; do
                 if [ "$ABI" = "default" -o "$ABI" = "$CPU_ABI" ] ; then
                     AT_LEAST_CPU_ABI_MATCH="yes"
                     for DIR in `ls -d $ROOTDIR/tests/device/*`; do
-                        log "Running device test on $DEVICE [$CPU_ABI]: $DIR"
                         if is_buildable $DIR; then
+                            log "Running device test on $DEVICE [$CPU_ABI]: $DIR"
                             run_device_test "$DEVICE" "$CPU_ABI" "$DIR" /data/local/tmp
                         fi
                     done
diff --git a/toolchains/arm-linux-androideabi-clang3.1/setup.mk b/toolchains/arm-linux-androideabi-clang3.1/setup.mk
index 188840e..482d8f8 100644
--- a/toolchains/arm-linux-androideabi-clang3.1/setup.mk
+++ b/toolchains/arm-linux-androideabi-clang3.1/setup.mk
@@ -47,8 +47,7 @@
 #
 
 TARGET_CFLAGS := \
-    -gcc-toolchain $(TOOLCHAIN_PREBUILT_ROOT) \
-    -isystem $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/lib/clang/$(LLVM_VERSION)/include \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
     -fpic \
     -ffunction-sections \
     -funwind-tables \
@@ -57,7 +56,7 @@
     -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__
 
 TARGET_LDFLAGS := \
-    -gcc-toolchain $(TOOLCHAIN_PREBUILT_ROOT)
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT))
 
 TARGET_C_INCLUDES := \
     $(SYSROOT)/usr/include
diff --git a/toolchains/mipsel-linux-android-clang3.1/setup.mk b/toolchains/mipsel-linux-android-clang3.1/setup.mk
index 4879d3f..5922a80 100644
--- a/toolchains/mipsel-linux-android-clang3.1/setup.mk
+++ b/toolchains/mipsel-linux-android-clang3.1/setup.mk
@@ -49,7 +49,7 @@
 LLVM_TRIPLE := mipsel-none-linux-android
 
 TARGET_CFLAGS := \
-        -gcc-toolchain $(TOOLCHAIN_PREBUILT_ROOT) \
+        -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
         -target $(LLVM_TRIPLE) \
         -fpic \
         -fno-strict-aliasing \
@@ -59,7 +59,7 @@
         -fmessage-length=0
 
 TARGET_LDFLAGS := \
-        -gcc-toolchain $(TOOLCHAIN_PREBUILT_ROOT) \
+        -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
         -target $(LLVM_TRIPLE)
 
 TARGET_C_INCLUDES := \
diff --git a/toolchains/x86-clang3.1/setup.mk b/toolchains/x86-clang3.1/setup.mk
index 58e2085..602af5f 100644
--- a/toolchains/x86-clang3.1/setup.mk
+++ b/toolchains/x86-clang3.1/setup.mk
@@ -45,7 +45,7 @@
 LLVM_TRIPLE := i686-none-linux-android
 
 TARGET_CFLAGS := \
-    -gcc-toolchain $(TOOLCHAIN_PREBUILT_ROOT) \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
     -target $(LLVM_TRIPLE) \
     -ffunction-sections \
     -funwind-tables \
@@ -57,7 +57,7 @@
 
 # Add and LDFLAGS for the target here
 TARGET_LDFLAGS := \
-    -gcc-toolchain $(TOOLCHAIN_PREBUILT_ROOT) \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_PREBUILT_ROOT)) \
     -target $(LLVM_TRIPLE)
 
 TARGET_x86_release_CFLAGS :=  -O2 \