Merge commit '81241a944099014cc56929a99355cede91ada83c' into HEAD

Conflicts:
	CMakeLists.txt
	cmake/config-ix.cmake
	include/locale
	src/locale.cpp
	src/thread.cpp
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2f0da84
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+#==============================================================================#
+# This file specifies intentionally untracked files that git should ignore.
+# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html
+#
+# This file is intentionally different from the output of `git svn show-ignore`,
+# as most of those are useless.
+#==============================================================================#
+
+#==============================================================================#
+# File extensions to be ignored anywhere in the tree.
+#==============================================================================#
+# Temp files created by most text editors.
+*~
+# Merge files created by git.
+*.orig
+# Byte compiled python modules.
+*.pyc
+# vim swap files
+.*.swp
+.sw?
+
+#==============================================================================#
+# Explicit files to ignore (only matches one).
+#==============================================================================#
+.gitusers
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..ac015a5
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,8 @@
+dschuff@chromium.org
+eliben@chromium.org
+jfb@chromium.org
+jvoung@chromium.org
+kschimpf@chromium.org
+mseaborn@chromium.org
+sehr@chromium.org
+stichnot@chromium.org
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
new file mode 100644
index 0000000..4d9f899
--- /dev/null
+++ b/PRESUBMIT.py
@@ -0,0 +1,66 @@
+# Copyright (c) 2013 The Native Client Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Documentation on PRESUBMIT.py can be found at:
+# http://www.chromium.org/developers/how-tos/depottools/presubmit-scripts
+
+EXCLUDE_PROJECT_CHECKS_DIRS = [ '.' ]
+
+import subprocess
+def CheckGitBranch():
+  p = subprocess.Popen("git branch -vv", shell=True,
+                       stdout=subprocess.PIPE)
+  output, _ = p.communicate()
+
+  lines = output.split('\n')
+  for line in lines:
+    # output format for checked-out branch should be
+    # * branchname hash [TrackedBranchName ...
+    toks = line.split()
+    if '*' not in toks[0]:
+      continue
+    if not 'origin/master' in toks[3]:
+      warning = 'Warning: your current branch:\n' + line
+      warning += '\nis not tracking origin/master. git cl push may silently '
+      warning += 'fail to push your change. To fix this, do\n'
+      warning += 'git branch -u origin/master'
+      return warning
+    return None
+  print 'Warning: presubmit check could not determine local git branch'
+  return None
+
+def _CommonChecks(input_api, output_api):
+  """Checks for both upload and commit."""
+  results = []
+  results.extend(input_api.canned_checks.PanProjectChecks(
+      input_api, output_api, project_name='Native Client',
+      excluded_paths=tuple(EXCLUDE_PROJECT_CHECKS_DIRS)))
+  branch_warning = CheckGitBranch()
+  if branch_warning:
+    results.append(output_api.PresubmitPromptWarning(branch_warning))
+  return results
+
+def CheckChangeOnUpload(input_api, output_api):
+  """Verifies all changes in all files.
+  Args:
+    input_api: the limited set of input modules allowed in presubmit.
+    output_api: the limited set of output modules allowed in presubmit.
+  """
+  report = []
+  report.extend(_CommonChecks(input_api, output_api))
+  return report
+
+def CheckChangeOnCommit(input_api, output_api):
+  """Verifies all changes in all files and verifies that the
+  tree is open and can accept a commit.
+  Args:
+    input_api: the limited set of input modules allowed in presubmit.
+    output_api: the limited set of output modules allowed in presubmit.
+  """
+  report = []
+  report.extend(CheckChangeOnUpload(input_api, output_api))
+  return report
+
+def GetPreferredTrySlaves(project, change):
+  return []
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index f0219c0..e8d6025 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -1,34 +1,39 @@
-include(CheckLibraryExists)
-include(CheckCXXCompilerFlag)
+# @LOCALMOD-START The PNaCl driver automatically adds dependencies to
+#                 libc++ which hasn't been built yet. The tests for
+#                 flags therefore fail because the library can't be
+#                 found. We should fix this in a different CL, and add
+#                 proper detection for newlib's lack of locale_t
+#                 support. See:
+#                  https://code.google.com/p/nativeclient/issues/detail?id=3661
 
-# Check compiler flags
-check_cxx_compiler_flag(-std=c++0x            LIBCXX_HAS_STDCXX0X_FLAG)
-check_cxx_compiler_flag(-fPIC                 LIBCXX_HAS_FPIC_FLAG)
-check_cxx_compiler_flag(-nodefaultlibs        LIBCXX_HAS_NODEFAULTLIBS_FLAG)
-check_cxx_compiler_flag(-nostdinc++           LIBCXX_HAS_NOSTDINCXX_FLAG)
-check_cxx_compiler_flag(-Wall                 LIBCXX_HAS_WALL_FLAG)
-check_cxx_compiler_flag(-W                    LIBCXX_HAS_W_FLAG)
-check_cxx_compiler_flag(-Wno-unused-parameter LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG)
-check_cxx_compiler_flag(-Wwrite-strings       LIBCXX_HAS_WWRITE_STRINGS_FLAG)
-check_cxx_compiler_flag(-Wno-long-long        LIBCXX_HAS_WNO_LONG_LONG_FLAG)
-check_cxx_compiler_flag(-pedantic             LIBCXX_HAS_PEDANTIC_FLAG)
-check_cxx_compiler_flag(-Werror               LIBCXX_HAS_WERROR_FLAG)
-check_cxx_compiler_flag(-Wno-error            LIBCXX_HAS_WNO_ERROR_FLAG)
-check_cxx_compiler_flag(-fno-exceptions       LIBCXX_HAS_FNO_EXCEPTIONS_FLAG)
-check_cxx_compiler_flag(-fno-rtti             LIBCXX_HAS_FNO_RTTI_FLAG)
-check_cxx_compiler_flag(/WX                   LIBCXX_HAS_WX_FLAG)
-check_cxx_compiler_flag(/WX-                  LIBCXX_HAS_NO_WX_FLAG)
-check_cxx_compiler_flag(/EHsc                 LIBCXX_HAS_EHSC_FLAG)
-check_cxx_compiler_flag(/EHs-                 LIBCXX_HAS_NO_EHS_FLAG)
-check_cxx_compiler_flag(/EHa-                 LIBCXX_HAS_NO_EHA_FLAG)
-check_cxx_compiler_flag(/GR-                  LIBCXX_HAS_NO_GR_FLAG)
+set(LIBCXX_HAS_STDCXX0X_FLAG 1)
+set(LIBCXX_HAS_FPIC_FLAG 0) # Not quite true, but untested in PNaCl.
+set(LIBCXX_HAS_NODEFAULTLIBS_FLAG 1)
+set(LIBCXX_HAS_NOSTDINCXX_FLAG 1)
+set(LIBCXX_HAS_WALL_FLAG 1)
+set(LIBCXX_HAS_W_FLAG 1)
+set(LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG 1)
+set(LIBCXX_HAS_WWRITE_STRINGS_FLAG 1)
+set(LIBCXX_HAS_WNO_LONG_LONG_FLAG 1)
+set(LIBCXX_HAS_PEDANTIC_FLAG 1)
+set(LIBCXX_HAS_WERROR_FLAG 1)
+set(LIBCXX_HAS_WNO_ERROR_FLAG 1)
+set(LIBCXX_HAS_FNO_EXCEPTIONS_FLAG 1)
+set(LIBCXX_HAS_FNO_RTTI_FLAG 1)
+# MSVC flags:
+set(LIBCXX_HAS_WX_FLAG 0)
+set(LIBCXX_HAS_NO_WX_FLAG 0)
+set(LIBCXX_HAS_EHSC_FLAG 0)
+set(LIBCXX_HAS_NO_EHS_FLAG 0)
+set(LIBCXX_HAS_NO_EHA_FLAG 0)
+set(LIBCXX_HAS_NO_GR_FLAG 0)
 
-# Check libraries
-check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
-check_library_exists(c printf "" LIBCXX_HAS_C_LIB)
-check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
-check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
-check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)
+set(LIBCXX_HAS_PTHREAD_LIB 1)
+set(LIBCXX_HAS_C_LIB 1)
+set(LIBCXX_HAS_M_LIB 1)
+set(LIBCXX_HAS_RT_LIB 0)
+set(LIBCXX_HAS_GCC_S_LIB 0)
+# @LOCALMOD-END
 
 # Check C++0x features
 if (LIBCXX_ENABLE_CXX0X)
diff --git a/codereview.settings b/codereview.settings
new file mode 100644
index 0000000..21c6452
--- /dev/null
+++ b/codereview.settings
@@ -0,0 +1,10 @@
+# This file is used by gcl to get repository specific information.
+CODE_REVIEW_SERVER: codereview.chromium.org
+CC_LIST: native-client-reviews@googlegroups.com
+VIEW_VC: https://gerrit.chromium.org/gerrit/gitweb?p=native_client/pnacl-libcxx.git;a=commit;h=
+STATUS: http://nativeclient-status.appspot.com/status
+TRY_ON_UPLOAD: False
+TRYSERVER_PROJECT: nacl
+TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-nacl
+PUSH_URL_CONFIG: url.ssh://gerrit.chromium.org.pushinsteadof
+ORIGIN_URL_CONFIG: http://chromium.googlesource.com
diff --git a/include/__locale b/include/__locale
index 2073e1b..e78c8ee 100644
--- a/include/__locale
+++ b/include/__locale
@@ -31,6 +31,66 @@
 #pragma GCC system_header
 #endif
 
+// @LOCALMOD-START Newlib doesn't have the following C extensions for
+//                 locales. This probably shouldn't rely on
+//                 _NEWLIB_VERSION: lack of locale_t support could
+//                 instead be detected at configuration time.
+#if defined(_NEWLIB_VERSION)
+typedef void *locale_t;
+extern "C" locale_t duplocale(locale_t);
+extern "C" void freelocale(locale_t);
+extern "C" locale_t newlocale(int, const char *, locale_t);
+extern "C" locale_t uselocale(locale_t);
+#define LC_COLLATE_MASK (1 << LC_COLLATE)
+#define LC_CTYPE_MASK (1 << LC_CTYPE)
+#define LC_MESSAGES_MASK (1 << LC_MESSAGES)
+#define LC_MONETARY_MASK (1 << LC_MONETARY)
+#define LC_NUMERIC_MASK (1 << LC_NUMERIC)
+#define LC_TIME_MASK (1 << LC_TIME)
+#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | \
+                     LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
+#define isxdigit_l(a, L) (((void) L), isxdigit(a))
+#define iswxdigit_l(a, L) (((void) L), iswxdigit(a))
+#define isdigit_l(a, L) (((void) L), isdigit(a))
+#define iswdigit_l(a, L) (((void) L), iswdigit(a))
+#define iswcntrl_l(a, L) (((void) L), iswcntrl(a))
+#define iswcntrl_l(a, L) (((void) L), iswcntrl(a))
+#define isalpha_l(a, L) (((void) L), isalpha(a))
+#define iswalpha_l(a, L) (((void) L), iswalpha(a))
+#define ispunct_l(a, L) (((void) L), ispunct(a))
+#define iswpunct_l(a, L) (((void) L), iswpunct(a))
+#define isblank_l(a, L) (((void) L), isblank(a))
+#define iswblank_l(a, L) (((void) L), iswblank(a))
+#define isspace_l(a, L) (((void) L), isspace(a))
+#define iswspace_l(a, L) (((void) L), iswspace(a))
+#define isprint_l(a, L) (((void) L), isprint(a))
+#define iswprint_l(a, L) (((void) L), iswprint(a))
+#define islower_l(a, L) (((void) L), islower(a))
+#define iswlower_l(a, L) (((void) L), iswlower(a))
+#define isupper_l(a, L) (((void) L), isupper(a))
+#define iswupper_l(a, L) (((void) L), iswupper(a))
+#define tolower_l(a, L) (((void) L), tolower(a))
+#define towlower_l(a, L) (((void) L), towlower(a))
+#define toupper_l(a, L) (((void) L), toupper(a))
+#define towupper_l(a, L) (((void) L), towupper(a))
+#define strftime_l(a, b, c, d, L) (((void) L), strftime(a, b, c, d))
+#define strtoll_l(a, b, c, L) (((void) L), strtoll(a, b, c))
+#define strtoull_l(a, b, c, L) (((void) L), strtoull(a, b, c))
+#define strtold_l(a, b, L) (((void) L), strtold(a, b))
+#define strcoll_l(a, b, L) (((void) L), strcoll(a, b))
+#define wstrcoll_l(a, b, L) (((void) L), wstrcoll(a, b))
+#define cscoll_l(a, b, L) (((void) L), cscoll(a, b))
+#define wcscoll_l(a, b, L) (((void) L), wcscoll(a, b))
+#define strxfrm_l(a, b, c, L) (((void) L), strxfrm(a, b, c))
+#define wstrxfrm_l(a, b, c, L) (((void) L), wstrxfrm(a, b, c))
+#define csxfrm_l(a, b, c, L) (((void) L), csxfrm(a, b, c))
+#define wcsxfrm_l(a, b, c, L) (((void) L), wcsxfrm(a, b, c))
+#define sscanf_l(a, b, L, ...) (((void) L), sscanf(a, b, ##__VA_ARGS__))
+#define snprintf_l(a, b, L, c, ...) (((void) L), snprintf(a, b, c, ##__VA_ARGS__))
+#define asprintf_l(a, L, b, ...) (((void) L), asprintf(a, b, ##__VA_ARGS__))
+#endif
+ // @LOCALMOD-END
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 class _LIBCPP_TYPE_VIS locale;
@@ -375,6 +435,21 @@
     static const mask punct  = _ISPUNCT;
     static const mask xdigit = _ISXDIGIT;
     static const mask blank  = _ISBLANK;
+// @LOCALMOD-START
+#elif defined(_NEWLIB_VERSION)
+    typedef char mask; // Same type as Newlib's _ctype_ array in ctype.h.
+    // Defined in Newlib's ctype.h.
+    static const mask space  = _S;
+    static const mask print  = _P | _U | _L | _N | _B;
+    static const mask cntrl  = _C;
+    static const mask upper  = _U;
+    static const mask lower  = _L;
+    static const mask alpha  = _U | _L;
+    static const mask digit  = _N;
+    static const mask punct  = _P;
+    static const mask xdigit = _X | _N;
+    static const mask blank  = _B;
+// @LOCALMOD-END
 #else  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || EMSCRIPTEN || __sun__
     typedef unsigned long mask;
     static const mask space  = 1<<0;
diff --git a/include/atomic b/include/atomic
index f6ab1cb..98f52a0 100644
--- a/include/atomic
+++ b/include/atomic
@@ -560,12 +560,24 @@
 {
     mutable _Atomic(_Tp) __a_;
 
+  // @LOCALMOD-BEGIN The NaCl builtin delays resolution of the lock-free
+  //                 property until translation time (time at which the
+  //                 actual target is known).
+#if defined (__pnacl__)
+    _LIBCPP_INLINE_VISIBILITY
+    bool is_lock_free() const volatile _NOEXCEPT
+        {return __nacl_atomic_is_lock_free(sizeof(_Tp), &__a_);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool is_lock_free() const _NOEXCEPT
+        {return __nacl_atomic_is_lock_free(sizeof(_Tp), &__a_);}
+#else
     _LIBCPP_INLINE_VISIBILITY
     bool is_lock_free() const volatile _NOEXCEPT
         {return __c11_atomic_is_lock_free(sizeof(_Tp));}
     _LIBCPP_INLINE_VISIBILITY
     bool is_lock_free() const _NOEXCEPT
         {return __c11_atomic_is_lock_free(sizeof(_Tp));}
+#endif // @LOCALMOD-END
     _LIBCPP_INLINE_VISIBILITY
     void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
         {__c11_atomic_store(&__a_, __d, __m);}
diff --git a/include/cmath b/include/cmath
index 75087ae..25a9b6b 100644
--- a/include/cmath
+++ b/include/cmath
@@ -1382,7 +1382,11 @@
 using ::log2f;
 
 inline _LIBCPP_INLINE_VISIBILITY float       log2(float __x) _NOEXCEPT       {return log2f(__x);}
+#if defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib. Note that PNaCl represents ``long double`` as ``double``, hence the intrinsic's type.
+inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __x) _NOEXCEPT {return __builtin_log2(__x);}
+#else
 inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __x) _NOEXCEPT {return log2l(__x);}
+#endif // @LOCALMOD-END
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1395,7 +1399,11 @@
 using ::logbf;
 
 inline _LIBCPP_INLINE_VISIBILITY float       logb(float __x) _NOEXCEPT       {return logbf(__x);}
+#if defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib. Note that PNaCl represents ``long double`` as ``double``, hence the intrinsic's type.
+inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __x) _NOEXCEPT {return __builtin_logb(__x);}
+#else
 inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __x) _NOEXCEPT {return logbl(__x);}
+#endif // @LOCALMOD-END
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1480,6 +1488,15 @@
 
 // nexttoward
 
+#if defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib. Note that PNaCl represents ``long double`` as ``double``, hence the intrinsic's type.
+inline _LIBCPP_INLINE_VISIBILITY float       nexttoward(float __x, long double __y) _NOEXCEPT       {return __builtin_nexttoward(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __x, long double __y) _NOEXCEPT {return __builtin_nexttoward(__x, __y);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+nexttoward(_A1 __x, long double __y) _NOEXCEPT {return __builtin_nexttoward((double)__x, __y);}
+#else
 using ::nexttoward;
 using ::nexttowardf;
 
@@ -1490,7 +1507,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
 nexttoward(_A1 __x, long double __y) _NOEXCEPT {return nexttoward((double)__x, __y);}
-
+#endif // @LOCALMOD-END
 // remainder
 
 using ::remainder;
@@ -1663,14 +1680,18 @@
 using ::llrintl;
 using ::llroundl;
 using ::log1pl;
+#if !defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib.
 using ::log2l;
 using ::logbl;
+#endif // @LOCALMOD-END
 using ::lrintl;
 using ::lroundl;
 using ::nanl;
 using ::nearbyintl;
 using ::nextafterl;
+#if !defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib.
 using ::nexttowardl;
+#endif // @LOCALMOD-END
 using ::remainderl;
 using ::remquol;
 using ::rintl;
diff --git a/include/cstdio b/include/cstdio
index ce3af4d..e7d8fab 100644
--- a/include/cstdio
+++ b/include/cstdio
@@ -172,8 +172,11 @@
 using ::fsetpos;
 using ::ftell;
 using ::rewind;
+#undef clearerr // @LOCALMOD
 using ::clearerr;
+#undef feof // @LOCALMOD
 using ::feof;
+#undef ferror // @LOCALMOD
 using ::ferror;
 using ::perror;
 
diff --git a/include/limits b/include/limits
index d917c57..1b8a87d 100644
--- a/include/limits
+++ b/include/limits
@@ -237,7 +237,7 @@
     static _LIBCPP_CONSTEXPR const bool is_bounded = true;
     static _LIBCPP_CONSTEXPR const bool is_modulo = true;
 
-#if __i386__ || __x86_64__
+#if __i386__ || __x86_64__ || defined(__pnacl__) // @LOCALMOD
     static _LIBCPP_CONSTEXPR const bool traps = true;
 #else
     static _LIBCPP_CONSTEXPR const bool traps = false;
diff --git a/include/locale b/include/locale
index d13d49e..cc0fcf6 100644
--- a/include/locale
+++ b/include/locale
@@ -193,6 +193,8 @@
 #include <ctime>
 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
 #include <support/win32/locale_win32.h>
+#elif defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
+// Nothing.
 #else // _LIBCPP_MSVCRT
 #include <nl_types.h>
 #endif  // !_LIBCPP_MSVCRT
@@ -229,7 +231,7 @@
 // OSX has nice foo_l() functions that let you turn off use of the global
 // locale.  Linux, not so much.  The following functions avoid the locale when
 // that's possible and otherwise do the wrong thing.  FIXME.
-#if defined(__linux__) || defined(EMSCRIPTEN) || defined(_AIX)
+#if defined(__linux__) || defined(EMSCRIPTEN) || defined(_AIX) || defined(_NEWLIB_VERSION) // @LOCALMOD
 
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
@@ -3673,7 +3675,7 @@
 typename messages<_CharT>::catalog
 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
 {
-#ifdef _WIN32
+#if defined(_WIN32) || defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
     return -1;
 #else // _WIN32
     catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
@@ -3688,7 +3690,7 @@
 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
                          const string_type& __dflt) const
 {
-#ifdef _WIN32
+#if defined(_WIN32) || defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
     return __dflt;
 #else // _WIN32
     string __ndflt;
@@ -3710,7 +3712,7 @@
 void
 messages<_CharT>::do_close(catalog __c) const
 {
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
     if (__c != -1)
         __c <<= 1;
     nl_catd __cat = (nl_catd)__c;
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index cec0bee..35076a1 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,5 +1,11 @@
 # Get sources
 file(GLOB LIBCXX_SOURCES ../src/*.cpp)
+
+# @LOCALMOD-START Bake libcxxabi into the libcxx build.
+file(GLOB LIBCXXABI_SOURCES ../../libcxxabi/src/*.cpp)
+list(APPEND LIBCXX_SOURCES ${LIBCXXABI_SOURCES})
+# @LOCALMOD-END
+
 if(WIN32)
   file(GLOB LIBCXX_WIN32_SOURCES ../src/support/win32/*.cpp)
   list(APPEND LIBCXX_SOURCES ${LIBCXX_WIN32_SOURCES})
diff --git a/src/locale.cpp b/src/locale.cpp
index 8fadbb6..79195a4 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -42,6 +42,17 @@
 #pragma clang diagnostic ignored "-Wsign-conversion"
 #endif
 
+// @LOCALMOD-START Newlib doesn't have the following C extensions for locales.
+#if defined(_NEWLIB_VERSION)
+extern "C" {
+  locale_t duplocale(locale_t) { return NULL; }
+  void freelocale(locale_t) { }
+  locale_t newlocale(int, const char *, locale_t) { return NULL; }
+  locale_t uselocale(locale_t) { return NULL; }
+}
+#endif
+ // @LOCALMOD-END
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #ifdef __cloc_defined
@@ -1035,6 +1046,10 @@
 // going to end up dereferencing it later...
 #elif defined(EMSCRIPTEN)
     return *__ctype_b_loc();
+#elif defined(_NEWLIB_VERSION) // @LOCALMOD-START
+    // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
+    return _ctype_ + 1;
+    // @LOCALMOD-END
 #elif defined(_AIX)
     return (const unsigned long *)__lc_ctype_ptr->obj->mask;
 #else
diff --git a/src/random.cpp b/src/random.cpp
index bd24f2e..f7f83c9 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -24,6 +24,11 @@
 #include <unistd.h>
 #endif // defined(_WIN32)
 #include <errno.h>
+// @LOCALMOD-START
+#if defined(__native_client__)
+#include <nacl/nacl_random.h>
+#endif
+// @LOCALMOD-END
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -47,22 +52,49 @@
 }
 #else
 random_device::random_device(const string& __token)
+// @LOCALMOD-START
+#if defined(__native_client__)
+{
+    if (__token != "/dev/urandom")
+        __throw_system_error(ENODEV, ("random device not supported " + __token).c_str());
+    int error = nacl_secure_random_init();
+    if (error)
+        __throw_system_error(error, ("random device failed to open " + __token).c_str());
+}
+#else
     : __f_(open(__token.c_str(), O_RDONLY))
 {
     if (__f_ <= 0)
         __throw_system_error(errno, ("random_device failed to open " + __token).c_str());
 }
+#endif
+// @LOCALMOD-END
 
 random_device::~random_device()
 {
+// @LOCALMOD-START
+#if !defined(__native_client__)
     close(__f_);
+#endif
+// @LOCALMOD-END
 }
 
 unsigned
 random_device::operator()()
 {
     unsigned r;
+// @LOCALMOD-START
+#if defined(__native_client__)
+    size_t bytes_written;
+    int error = nacl_secure_random(&r, sizeof(r), &bytes_written);
+    if (error != 0)
+        __throw_system_error(error, "random_device failed getting bytes");
+    else if (bytes_written != sizeof(r))
+        __throw_runtime_error("random_device failed obtaining enough bytes");
+#else
     read(__f_, &r, sizeof(r));
+#endif
+// @LOCALMOD-END
     return r;
 }
 #endif // defined(_WIN32)
diff --git a/src/thread.cpp b/src/thread.cpp
index 338a8a2..a7351cf 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -14,7 +14,7 @@
 #include "limits"
 #include <sys/types.h>
 #if !defined(_WIN32)
-#if !defined(__sun__) && !defined(__linux__) && !defined(_AIX)
+#if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) // @LOCALMOD
 #include <sys/sysctl.h>
 #endif // !__sun__ && !__linux__ && !_AIX
 #include <unistd.h>
diff --git a/test/lit.cfg b/test/lit.cfg
index aa45439..a49baae 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -118,7 +118,10 @@
                 report += "\n\nExpected compilation to fail!"
                 return lit.Test.FAIL, report
         else:
-            exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
+            # @LOCALMOD-START
+            exec_file = tempfile.NamedTemporaryFile(
+                suffix=exe_suffix, delete=False)
+            # @LOCALMOD-END
             exec_path = exec_file.name
             exec_file.close()
 
@@ -144,6 +147,10 @@
                     cmd.extend('%s=%s' % (name, value)
                                for name,value in self.exec_env.items())
                 cmd.append(exec_path)
+                # @LOCALMOD-START
+                if shell_prefix:
+                  cmd = shell_prefix + cmd
+                # @LOCALMOD-END
                 if lit_config.useValgrind:
                     cmd = lit_config.valgrindArgs + cmd
                 out, err, exitCode = self.execute_command(cmd, source_dir)
@@ -281,8 +288,12 @@
 
 config.test_format = LibcxxTestFormat(
     cxx_under_test,
-    cpp_flags = ['-nostdinc++'] + compile_flags + include_paths,
-    ld_flags = ['-nodefaultlibs'] + library_paths + ['-lc++'] + link_flags,
+    # @LOCALMOD-START
+    cpp_flags = (([] if use_system_lib else ['-nostdinc++']) +
+                 compile_flags + include_paths),
+    ld_flags = (([] if use_system_lib else ['-nodefaultlibs', '-lc++']) +
+                library_paths + link_flags),
+    # @LOCALMOD-END
     exec_env = exec_env)
 
 # Get or infer the target triple.
@@ -293,6 +304,16 @@
         [cxx_under_test, '-dumpmachine']).strip()
     lit_config.note("inferred target_triple as: %r" % (config.target_triple,))
 
+# @LOCALMOD-START
+# Executable suffix.
+exe_suffix = lit.params.get('exe_suffix', "exe")
+
+# Prefix the executable command with a shell.
+shell_prefix = lit.params.get('shell_prefix', None)
+if shell_prefix:
+  shell_prefix = shlex.split(shell_prefix)
+# @LOCALMOD-END
+
 # Write an "available feature" that combines the triple when use_system_lib is
 # enabled. This is so that we can easily write XFAIL markers for tests that are
 # known to fail with versions of libc++ as were shipped with a particular