Merge "Fix the 16 bit/32 bit instruction check for arm."
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..ea19538
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,14 @@
+BasedOnStyle: Google
+AllowShortBlocksOnASingleLine: false
+AllowShortFunctionsOnASingleLine: false
+
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+IndentWidth: 2
+ContinuationIndentWidth: 2
+PointerAlignment: Left
+TabWidth: 2
+UseTab: Never
+PenaltyExcessCharacter: 32
+
+Cpp11BracedListStyle: false
diff --git a/benchmarks/math_benchmark.cpp b/benchmarks/math_benchmark.cpp
index 2e0c962..ed5b56c 100644
--- a/benchmarks/math_benchmark.cpp
+++ b/benchmarks/math_benchmark.cpp
@@ -258,3 +258,29 @@
 
   StopBenchmarkTiming();
 }
+
+BENCHMARK_WITH_ARG(BM_math_fabs_macro, double)->AT_COMMON_VALS;
+void BM_math_fabs_macro::Run(int iters, double value) {
+  StartBenchmarkTiming();
+
+  d = 0.0;
+  v = value;
+  for (int i = 0; i < iters; ++i) {
+    d += fabs(v);
+  }
+
+  StopBenchmarkTiming();
+}
+
+BENCHMARK_WITH_ARG(BM_math_fabs, double)->AT_COMMON_VALS;
+void BM_math_fabs::Run(int iters, double value) {
+  StartBenchmarkTiming();
+
+  d = 0.0;
+  v = value;
+  for (int i = 0; i < iters; ++i) {
+    d += (fabs)(v);
+  }
+
+  StopBenchmarkTiming();
+}
diff --git a/libc/Android.mk b/libc/Android.mk
index ca20d3d..437f8b2 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -214,6 +214,7 @@
     bionic/socket.cpp \
     bionic/stat.cpp \
     bionic/statvfs.cpp \
+    bionic/strchrnul.cpp \
     bionic/strerror.cpp \
     bionic/strerror_r.cpp \
     bionic/strsignal.cpp \
diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk
index b5283f6..58c5eb6 100644
--- a/libc/arch-arm/arm.mk
+++ b/libc/arch-arm/arm.mk
@@ -39,6 +39,7 @@
     arch-arm/bionic/__bionic_clone.S \
     arch-arm/bionic/_exit_with_stack_teardown.S \
     arch-arm/bionic/libgcc_compat.c \
+    arch-arm/bionic/popcount_tab.c \
     arch-arm/bionic/__restore.S \
     arch-arm/bionic/setjmp.S \
     arch-arm/bionic/syscall.S \
diff --git a/libc/arch-arm/bionic/popcount_tab.c b/libc/arch-arm/bionic/popcount_tab.c
new file mode 100644
index 0000000..eb2faa9
--- /dev/null
+++ b/libc/arch-arm/bionic/popcount_tab.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// Export this to maintain ABI compatibilty with libgcc, since compiler-rt
+// doesn't use a table-driven implementation of __popcount.
+const unsigned char __popcount_tab[256] = {
+  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,
+  3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4,
+  3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4,
+  4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
+  3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2,
+  2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,
+  4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5,
+  5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5,
+  5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
diff --git a/libc/bionic/strchrnul.cpp b/libc/bionic/strchrnul.cpp
new file mode 100644
index 0000000..55422e0
--- /dev/null
+++ b/libc/bionic/strchrnul.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+extern "C" const char* strchrnul(const char* s, int ch) {
+  while (*s && *s != ch) {
+    ++s;
+  }
+  return s;
+}
diff --git a/libc/include/string.h b/libc/include/string.h
index d32c164..2c50cfa 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -53,6 +53,14 @@
 
 extern char*  strchr(const char *, int) __purefunc;
 extern char* __strchr_chk(const char *, int, size_t);
+#if defined(__USE_GNU)
+#if defined(__cplusplus)
+extern "C++" char* strchrnul(char*, int) __RENAME(strchrnul) __purefunc;
+extern "C++" const char* strchrnul(const char*, int) __RENAME(strchrnul) __purefunc;
+#else
+char* strchrnul(const char*, int) __purefunc;
+#endif
+#endif
 
 extern char*  strrchr(const char *, int) __purefunc;
 extern char* __strrchr_chk(const char *, int, size_t);
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index 399458e..9e3c653 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -82,12 +82,6 @@
 #define NGREG 34 /* x0..x30 + sp + pc + pstate */
 typedef unsigned long greg_t;
 typedef greg_t gregset_t[NGREG];
-
-struct user_fpsimd_struct {
-  long double vregs[32];
-  uint32_t fpsr;
-  uint32_t fpcr;
-};
 typedef struct user_fpsimd_struct fpregset_t;
 
 #include <asm/sigcontext.h>
diff --git a/libc/include/sys/user.h b/libc/include/sys/user.h
index ce4c07c..3312981 100644
--- a/libc/include/sys/user.h
+++ b/libc/include/sys/user.h
@@ -232,7 +232,17 @@
 
 #elif defined(__aarch64__)
 
-// There are no user structures for 64 bit arm.
+struct user_regs_struct {
+  uint64_t regs[31];
+  uint64_t sp;
+  uint64_t pc;
+  uint64_t pstate;
+};
+struct user_fpsimd_struct {
+  __uint128_t vregs[32];
+  uint32_t fpsr;
+  uint32_t fpcr;
+};
 
 #else
 
diff --git a/libc/libc.map b/libc/libc.map
index 4670079..9456920 100644
--- a/libc/libc.map
+++ b/libc/libc.map
@@ -1342,6 +1342,7 @@
     __write_chk;
     getgrgid_r;
     getgrnam_r;
+    strchrnul;
 } LIBC;
 
 LIBC_PRIVATE {
diff --git a/libc/tools/zoneinfo/ZoneCompactor.java b/libc/tools/zoneinfo/ZoneCompactor.java
deleted file mode 100644
index 2d598fe..0000000
--- a/libc/tools/zoneinfo/ZoneCompactor.java
+++ /dev/null
@@ -1,192 +0,0 @@
-
-import java.io.*;
-import java.util.*;
-
-// usage: java ZoneCompiler <setup file> <data directory> <output directory> <tzdata version>
-//
-// Compile a set of tzfile-formatted files into a single file containing an index.
-//
-// The compilation is controlled by a setup file, which is provided as a
-// command-line argument.  The setup file has the form:
-//
-// Link <toName> <fromName>
-// ...
-// <zone filename>
-// ...
-//
-// Note that the links must be declared prior to the zone names.
-// A zone name is a filename relative to the source directory such as
-// 'GMT', 'Africa/Dakar', or 'America/Argentina/Jujuy'.
-//
-// Use the 'zic' command-line tool to convert from flat files
-// (such as 'africa' or 'northamerica') to a directory
-// hierarchy suitable for this tool (containing files such as 'data/Africa/Abidjan').
-//
-
-public class ZoneCompactor {
-  // Maximum number of characters in a zone name, including '\0' terminator.
-  private static final int MAXNAME = 40;
-
-  // Zone name synonyms.
-  private Map<String,String> links = new HashMap<String,String>();
-
-  // File offsets by zone name.
-  private Map<String,Integer> offsets = new HashMap<String,Integer>();
-
-  // File lengths by zone name.
-  private Map<String,Integer> lengths = new HashMap<String,Integer>();
-
-  // Concatenate the contents of 'inFile' onto 'out'.
-  private static void copyFile(File inFile, OutputStream out) throws Exception {
-    byte[] ret = new byte[0];
-
-    InputStream in = new FileInputStream(inFile);
-    byte[] buf = new byte[8192];
-    while (true) {
-      int nbytes = in.read(buf);
-      if (nbytes == -1) {
-        break;
-      }
-      out.write(buf, 0, nbytes);
-
-      byte[] nret = new byte[ret.length + nbytes];
-      System.arraycopy(ret, 0, nret, 0, ret.length);
-      System.arraycopy(buf, 0, nret, ret.length, nbytes);
-      ret = nret;
-    }
-    out.flush();
-  }
-
-  public ZoneCompactor(String setupFile, String dataDirectory, String zoneTabFile, String outputDirectory, String version) throws Exception {
-    // Read the setup file and concatenate all the data.
-    ByteArrayOutputStream allData = new ByteArrayOutputStream();
-    BufferedReader reader = new BufferedReader(new FileReader(setupFile));
-    String s;
-    int offset = 0;
-    while ((s = reader.readLine()) != null) {
-      s = s.trim();
-      if (s.startsWith("Link")) {
-        StringTokenizer st = new StringTokenizer(s);
-        st.nextToken();
-        String to = st.nextToken();
-        String from = st.nextToken();
-        links.put(from, to);
-      } else {
-        String link = links.get(s);
-        if (link == null) {
-          File sourceFile = new File(dataDirectory, s);
-          long length = sourceFile.length();
-          offsets.put(s, offset);
-          lengths.put(s, (int) length);
-
-          offset += length;
-          copyFile(sourceFile, allData);
-        }
-      }
-    }
-    reader.close();
-
-    // Fill in fields for links.
-    Iterator<String> it = links.keySet().iterator();
-    while (it.hasNext()) {
-      String from = it.next();
-      String to = links.get(from);
-
-      offsets.put(from, offsets.get(to));
-      lengths.put(from, lengths.get(to));
-    }
-
-    // Create/truncate the destination file.
-    RandomAccessFile f = new RandomAccessFile(new File(outputDirectory, "tzdata"), "rw");
-    f.setLength(0);
-
-    // Write the header.
-
-    // byte[12] tzdata_version -- 'tzdata2012f\0'
-    // int index_offset -- so we can slip in extra header fields in a backwards-compatible way
-    // int data_offset
-    // int zonetab_offset
-
-    // tzdata_version
-    f.write(toAscii(new byte[12], version));
-
-    // Write dummy values for the three offsets, and remember where we need to seek back to later
-    // when we have the real values.
-    int index_offset_offset = (int) f.getFilePointer();
-    f.writeInt(0);
-    int data_offset_offset = (int) f.getFilePointer();
-    f.writeInt(0);
-    int zonetab_offset_offset = (int) f.getFilePointer();
-    f.writeInt(0);
-
-    int index_offset = (int) f.getFilePointer();
-
-    // Write the index.
-    ArrayList<String> sortedOlsonIds = new ArrayList<String>();
-    sortedOlsonIds.addAll(offsets.keySet());
-    Collections.sort(sortedOlsonIds);
-    it = sortedOlsonIds.iterator();
-    while (it.hasNext()) {
-      String zoneName = it.next();
-      if (zoneName.length() >= MAXNAME) {
-        throw new RuntimeException("zone filename too long: " + zoneName.length());
-      }
-
-      // Follow the chain of links to work out where the real data for this zone lives.
-      String actualZoneName = zoneName;
-      while (links.get(actualZoneName) != null) {
-        actualZoneName = links.get(actualZoneName);
-      }
-
-      f.write(toAscii(new byte[MAXNAME], zoneName));
-      f.writeInt(offsets.get(actualZoneName));
-      f.writeInt(lengths.get(actualZoneName));
-      f.writeInt(0); // Used to be raw GMT offset. No longer used.
-    }
-
-    int data_offset = (int) f.getFilePointer();
-
-    // Write the data.
-    f.write(allData.toByteArray());
-
-    int zonetab_offset = (int) f.getFilePointer();
-
-    // Copy the zone.tab.
-    reader = new BufferedReader(new FileReader(zoneTabFile));
-    while ((s = reader.readLine()) != null) {
-      if (!s.startsWith("#")) {
-        f.writeBytes(s);
-        f.write('\n');
-      }
-    }
-    reader.close();
-
-    // Go back and fix up the offsets in the header.
-    f.seek(index_offset_offset);
-    f.writeInt(index_offset);
-    f.seek(data_offset_offset);
-    f.writeInt(data_offset);
-    f.seek(zonetab_offset_offset);
-    f.writeInt(zonetab_offset);
-
-    f.close();
-  }
-
-  private static byte[] toAscii(byte[] dst, String src) {
-    for (int i = 0; i < src.length(); ++i) {
-      if (src.charAt(i) > '~') {
-        throw new RuntimeException("non-ASCII string: " + src);
-      }
-      dst[i] = (byte) src.charAt(i);
-    }
-    return dst;
-  }
-
-  public static void main(String[] args) throws Exception {
-    if (args.length != 5) {
-      System.err.println("usage: java ZoneCompactor <setup file> <data directory> <zone.tab file> <output directory> <tzdata version>");
-      System.exit(0);
-    }
-    new ZoneCompactor(args[0], args[1], args[2], args[3], args[4]);
-  }
-}
diff --git a/libc/tools/zoneinfo/update-tzdata.py b/libc/tools/zoneinfo/update-tzdata.py
deleted file mode 100755
index 68a5ff5..0000000
--- a/libc/tools/zoneinfo/update-tzdata.py
+++ /dev/null
@@ -1,262 +0,0 @@
-#!/usr/bin/python
-
-"""Updates the timezone data held in bionic and ICU."""
-
-import ftplib
-import glob
-import httplib
-import os
-import re
-import shutil
-import subprocess
-import sys
-import tarfile
-import tempfile
-
-regions = ['africa', 'antarctica', 'asia', 'australasia',
-           'etcetera', 'europe', 'northamerica', 'southamerica',
-           # These two deliberately come last so they override what came
-           # before (and each other).
-           'backward', 'backzone' ]
-
-def CheckDirExists(dir, dirname):
-  if not os.path.isdir(dir):
-    print "Couldn't find %s (%s)!" % (dirname, dir)
-    sys.exit(1)
-
-bionic_libc_tools_zoneinfo_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
-
-# Find the bionic directory, searching upward from this script.
-bionic_dir = os.path.realpath('%s/../../..' % bionic_libc_tools_zoneinfo_dir)
-bionic_libc_zoneinfo_dir = '%s/libc/zoneinfo' % bionic_dir
-CheckDirExists(bionic_libc_zoneinfo_dir, 'bionic/libc/zoneinfo')
-CheckDirExists(bionic_libc_tools_zoneinfo_dir, 'bionic/libc/tools/zoneinfo')
-print 'Found bionic in %s ...' % bionic_dir
-
-# Find the icu directory.
-icu_dir = os.path.realpath('%s/../external/icu' % bionic_dir)
-icu4c_dir = os.path.realpath('%s/icu4c/source' % icu_dir)
-icu4j_dir = os.path.realpath('%s/icu4j' % icu_dir)
-CheckDirExists(icu4c_dir, 'external/icu/icu4c/source')
-CheckDirExists(icu4j_dir, 'external/icu/icu4j')
-print 'Found icu in %s ...' % icu_dir
-
-
-def GetCurrentTzDataVersion():
-  return open('%s/tzdata' % bionic_libc_zoneinfo_dir).read().split('\x00', 1)[0]
-
-
-def WriteSetupFile():
-  """Writes the list of zones that ZoneCompactor should process."""
-  links = []
-  zones = []
-  for region in regions:
-    for line in open('extracted/%s' % region):
-      fields = line.split()
-      if fields:
-        if fields[0] == 'Link':
-          links.append('%s %s %s' % (fields[0], fields[1], fields[2]))
-          zones.append(fields[2])
-        elif fields[0] == 'Zone':
-          zones.append(fields[1])
-  zones.sort()
-
-  setup = open('setup', 'w')
-  for link in sorted(set(links)):
-    setup.write('%s\n' % link)
-  for zone in sorted(set(zones)):
-    setup.write('%s\n' % zone)
-  setup.close()
-
-
-def SwitchToNewTemporaryDirectory():
-  tmp_dir = tempfile.mkdtemp('-tzdata')
-  os.chdir(tmp_dir)
-  print 'Created temporary directory "%s"...' % tmp_dir
-
-
-def FtpRetrieveFile(ftp, filename):
-  ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
-
-
-def FtpRetrieveFileAndSignature(ftp, data_filename):
-  """Downloads and repackages the given data from the given FTP server."""
-  print 'Downloading data...'
-  FtpRetrieveFile(ftp, data_filename)
-
-  print 'Downloading signature...'
-  signature_filename = '%s.asc' % data_filename
-  FtpRetrieveFile(ftp, signature_filename)
-
-
-def HttpRetrieveFile(http, path, output_filename):
-  http.request("GET", path)
-  f = open(output_filename, 'wb')
-  f.write(http.getresponse().read())
-  f.close()
-
-
-def HttpRetrieveFileAndSignature(http, data_filename):
-  """Downloads and repackages the given data from the given HTTP server."""
-  path = "/time-zones/repository/releases/%s" % data_filename
-
-  print 'Downloading data...'
-  HttpRetrieveFile(http, path, data_filename)
-
-  print 'Downloading signature...'
-  signature_filename = '%s.asc' % data_filename
-  HttpRetrievefile(http, "%s.asc" % path, signature_filename)
-
-
-def BuildIcuToolsAndData(data_filename):
-  # Keep track of the original cwd so we can go back to it at the end.
-  original_working_dir = os.getcwd()
-
-  # Create a directory to run 'make' from.
-  icu_working_dir = '%s/icu' % original_working_dir
-  os.mkdir(icu_working_dir)
-  os.chdir(icu_working_dir)
-
-  # Build the ICU tools.
-  print 'Configuring ICU tools...'
-  subprocess.check_call(['%s/runConfigureICU' % icu4c_dir, 'Linux'])
-
-  # Run the ICU tools.
-  os.chdir('tools/tzcode')
-
-  # The tz2icu tool only picks up icuregions and icuzones in they are in the CWD
-  for icu_data_file in [ 'icuregions', 'icuzones']:
-    icu_data_file_source = '%s/tools/tzcode/%s' % (icu4c_dir, icu_data_file)
-    icu_data_file_symlink = './%s' % icu_data_file
-    os.symlink(icu_data_file_source, icu_data_file_symlink)
-
-  shutil.copyfile('%s/%s' % (original_working_dir, data_filename), data_filename)
-  print 'Making ICU data...'
-  # The Makefile assumes the existence of the bin directory.
-  os.mkdir('%s/bin' % icu_working_dir)
-  subprocess.check_call(['make'])
-
-  # Copy the source file to its ultimate destination.
-  icu_txt_data_dir = '%s/data/misc' % icu4c_dir
-  print 'Copying zoneinfo64.txt to %s ...' % icu_txt_data_dir
-  shutil.copy('zoneinfo64.txt', icu_txt_data_dir)
-
-  # Regenerate the .dat file.
-  os.chdir(icu_working_dir)
-  subprocess.check_call(['make', 'INCLUDE_UNI_CORE_DATA=1', '-j32'])
-
-  # Copy the .dat file to its ultimate destination.
-  icu_dat_data_dir = '%s/stubdata' % icu4c_dir
-  datfiles = glob.glob('data/out/tmp/icudt??l.dat')
-  if len(datfiles) != 1:
-    print 'ERROR: Unexpectedly found %d .dat files (%s). Halting.' % (len(datfiles), datfiles)
-    sys.exit(1)
-  datfile = datfiles[0]
-  print 'Copying %s to %s ...' % (datfile, icu_dat_data_dir)
-  shutil.copy(datfile, icu_dat_data_dir)
-
-  # Generate the ICU4J .jar files
-  os.chdir('%s/data' % icu_working_dir)
-  subprocess.check_call(['make', 'icu4j-data'])
-
-  # Copy the ICU4J .jar files to their ultimate destination.
-  icu_jar_data_dir = '%s/main/shared/data' % icu4j_dir
-  jarfiles = glob.glob('out/icu4j/*.jar')
-  if len(jarfiles) != 2:
-    print 'ERROR: Unexpectedly found %d .jar files (%s). Halting.' % (len(jarfiles), jarfiles)
-    sys.exit(1)
-  for jarfile in jarfiles:
-    print 'Copying %s to %s ...' % (jarfile, icu_jar_data_dir)
-    shutil.copy(jarfile, icu_jar_data_dir)
-
-  # Switch back to the original working cwd.
-  os.chdir(original_working_dir)
-
-
-def CheckSignature(data_filename):
-  signature_filename = '%s.asc' % data_filename
-  print 'Verifying signature...'
-  # If this fails for you, you probably need to import Paul Eggert's public key:
-  # gpg --recv-keys ED97E90E62AA7E34
-  subprocess.check_call(['gpg', '--trusted-key=ED97E90E62AA7E34', '--verify',
-                         signature_filename, data_filename])
-
-
-def BuildBionicToolsAndData(data_filename):
-  new_version = re.search('(tzdata.+)\\.tar\\.gz', data_filename).group(1)
-
-  print 'Extracting...'
-  os.mkdir('extracted')
-  tar = tarfile.open(data_filename, 'r')
-  tar.extractall('extracted')
-
-  print 'Calling zic(1)...'
-  os.mkdir('data')
-  zic_inputs = [ 'extracted/%s' % x for x in regions ]
-  zic_cmd = ['zic', '-d', 'data' ]
-  zic_cmd.extend(zic_inputs)
-  subprocess.check_call(zic_cmd)
-
-  WriteSetupFile()
-
-  print 'Calling ZoneCompactor to update bionic to %s...' % new_version
-  subprocess.check_call(['javac', '-d', '.',
-                         '%s/ZoneCompactor.java' % bionic_libc_tools_zoneinfo_dir])
-  subprocess.check_call(['java', 'ZoneCompactor',
-                         'setup', 'data', 'extracted/zone.tab',
-                         bionic_libc_zoneinfo_dir, new_version])
-
-
-# Run with no arguments from any directory, with no special setup required.
-# See http://www.iana.org/time-zones/ for more about the source of this data.
-def main():
-  print 'Looking for new tzdata...'
-
-  tzdata_filenames = []
-
-  # The FTP server lets you download intermediate releases, and also lets you
-  # download the signatures for verification, so it's your best choice.
-  use_ftp = True
-
-  if use_ftp:
-    ftp = ftplib.FTP('ftp.iana.org')
-    ftp.login()
-    ftp.cwd('tz/releases')
-    for filename in ftp.nlst():
-      if filename.startswith('tzdata20') and filename.endswith('.tar.gz'):
-        tzdata_filenames.append(filename)
-    tzdata_filenames.sort()
-  else:
-    http = httplib.HTTPConnection('www.iana.org')
-    http.request("GET", "/time-zones")
-    index_lines = http.getresponse().read().split('\n')
-    for line in index_lines:
-      m = re.compile('.*href="/time-zones/repository/releases/(tzdata20\d\d\c\.tar\.gz)".*').match(line)
-      if m:
-        tzdata_filenames.append(m.group(1))
-
-  # If you're several releases behind, we'll walk you through the upgrades
-  # one by one.
-  current_version = GetCurrentTzDataVersion()
-  current_filename = '%s.tar.gz' % current_version
-  for filename in tzdata_filenames:
-    if filename > current_filename:
-      print 'Found new tzdata: %s' % filename
-      SwitchToNewTemporaryDirectory()
-      if use_ftp:
-        FtpRetrieveFileAndSignature(ftp, filename)
-      else:
-        HttpRetrieveFileAndSignature(http, filename)
-
-      CheckSignature(filename)
-      BuildIcuToolsAndData(filename)
-      BuildBionicToolsAndData(filename)
-      print 'Look in %s and %s for new data files' % (bionic_dir, icu_dir)
-      sys.exit(0)
-
-  print 'You already have the latest tzdata (%s)!' % current_version
-  sys.exit(0)
-
-
-if __name__ == '__main__':
-  main()
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
index 4e4f6a7..f22464e 100644
--- a/libc/zoneinfo/tzdata
+++ b/libc/zoneinfo/tzdata
Binary files differ
diff --git a/libm/Android.mk b/libm/Android.mk
index 7b28f70..d447417 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -108,8 +108,6 @@
     upstream-freebsd/lib/msun/src/s_exp2.c \
     upstream-freebsd/lib/msun/src/s_exp2f.c \
     upstream-freebsd/lib/msun/src/s_expm1f.c \
-    upstream-freebsd/lib/msun/src/s_fabs.c \
-    upstream-freebsd/lib/msun/src/s_fabsf.c \
     upstream-freebsd/lib/msun/src/s_fdim.c \
     upstream-freebsd/lib/msun/src/s_finite.c \
     upstream-freebsd/lib/msun/src/s_finitef.c \
@@ -175,7 +173,6 @@
     upstream-freebsd/lib/msun/src/s_copysignl.c \
     upstream-freebsd/lib/msun/src/e_coshl.c \
     upstream-freebsd/lib/msun/src/s_cosl.c \
-    upstream-freebsd/lib/msun/src/s_fabsl.c \
     upstream-freebsd/lib/msun/src/s_floorl.c \
     upstream-freebsd/lib/msun/src/s_fmal.c \
     upstream-freebsd/lib/msun/src/s_fmaxl.c \
@@ -228,6 +225,10 @@
 LOCAL_SRC_FILES += \
     signbit.c \
 
+# Home-grown stuff.
+LOCAL_SRC_FILES += \
+    fabs.cpp \
+
 # Arch specific optimizations.
 
 # -----------------------------------------------------------------------------
@@ -481,6 +482,7 @@
 LOCAL_CLANG := $(libm_clang)
 LOCAL_ARM_MODE := arm
 LOCAL_CFLAGS := \
+    -D__BIONIC_NO_MATH_INLINES \
     -DFLT_EVAL_METHOD=0 \
     -include $(LOCAL_PATH)/freebsd-compat.h \
     -Wno-missing-braces \
diff --git a/libm/fabs.cpp b/libm/fabs.cpp
new file mode 100644
index 0000000..add73fe
--- /dev/null
+++ b/libm/fabs.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 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 <math.h>
+
+#include "fpmath.h"
+
+double fabs(double x) {
+#if __arm__
+  // Both Clang and GCC insist on moving r0/r1 into a double register
+  // and using fabs where bit-twiddling would be a better choice.
+  // They get fabsf right, but we need to be careful in fabsl too.
+  IEEEd2bits u;
+  u.d = x;
+  u.bits.sign = 0;
+  return u.d;
+#else
+  return __builtin_fabs(x);
+#endif
+}
+
+float fabsf(float x) {
+  return __builtin_fabsf(x);
+}
+
+#if defined(__LP64__)
+long double fabsl(long double x) { return __builtin_fabsl(x); }
+#else
+long double fabsl(long double x) {
+  // Don't use __builtin_fabs here because of ARM. (See fabs above.)
+  return fabs(x);
+}
+#endif
diff --git a/libm/fake_long_double.c b/libm/fake_long_double.c
index 317a115..5edf839 100644
--- a/libm/fake_long_double.c
+++ b/libm/fake_long_double.c
@@ -25,7 +25,6 @@
  */
 
 long double copysignl(long double a1, long double a2) { return copysign(a1, a2); }
-long double fabsl(long double a1) { return fabs(a1); }
 long double fmaxl(long double a1, long double a2) { return fmax(a1, a2); }
 long double fmodl(long double a1, long double a2) { return fmod(a1, a2); }
 long double fminl(long double a1, long double a2) { return fmin(a1, a2); }
diff --git a/libm/include/math.h b/libm/include/math.h
index bc48b6a..ce8e3b2 100644
--- a/libm/include/math.h
+++ b/libm/include/math.h
@@ -20,6 +20,12 @@
 #include <sys/cdefs.h>
 #include <limits.h>
 
+#if !defined(__BIONIC_NO_MATH_INLINES)
+#define __BIONIC_MATH_INLINE(__def) extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__)) __def
+#else
+#define __BIONIC_MATH_INLINE(__def)
+#endif
+
 __BEGIN_DECLS
 #pragma GCC visibility push(default)
 
@@ -161,6 +167,7 @@
 
 double	ceil(double);
 double	fabs(double) __pure2;
+__BIONIC_MATH_INLINE(double fabs(double x) { return __builtin_fabs(x); })
 double	floor(double);
 double	fmod(double, double);
 
@@ -279,6 +286,7 @@
 
 float	ceilf(float);
 float	fabsf(float) __pure2;
+__BIONIC_MATH_INLINE(float fabsf(float x) { return __builtin_fabsf(x); })
 float	floorf(float);
 float	fmodf(float, float);
 float	roundf(float);
@@ -366,6 +374,7 @@
 long double	expl(long double);
 long double	expm1l(long double);
 long double	fabsl(long double) __pure2;
+__BIONIC_MATH_INLINE(long double fabsl(long double x) { return __builtin_fabsl(x); })
 long double	fdiml(long double, long double);
 long double	floorl(long double);
 long double	fmal(long double, long double, long double);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fabs.c b/libm/upstream-freebsd/lib/msun/src/s_fabs.c
deleted file mode 100644
index 15529e5..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_fabs.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* @(#)s_fabs.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#ifndef lint
-static char rcsid[] = "$FreeBSD$";
-#endif
-
-/*
- * fabs(x) returns the absolute value of x.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-fabs(double x)
-{
-	u_int32_t high;
-	GET_HIGH_WORD(high,x);
-	SET_HIGH_WORD(x,high&0x7fffffff);
-        return x;
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fabsf.c b/libm/upstream-freebsd/lib/msun/src/s_fabsf.c
deleted file mode 100644
index e9383d0..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_fabsf.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* s_fabsf.c -- float version of s_fabs.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * fabsf(x) returns the absolute value of x.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-fabsf(float x)
-{
-	u_int32_t ix;
-	GET_FLOAT_WORD(ix,x);
-	SET_FLOAT_WORD(x,ix&0x7fffffff);
-        return x;
-}
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index cf90045..80190d7 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -454,6 +454,13 @@
   }
 }
 
+TEST(string, strchrnul) {
+  const char* s = "01234222";
+  EXPECT_TRUE(strchrnul(s, '2') == &s[2]);
+  EXPECT_TRUE(strchrnul(s, '8') == (s + strlen(s)));
+  EXPECT_TRUE(strchrnul(s, '\0') == (s + strlen(s)));
+}
+
 TEST(string, strcmp) {
   StringTestState<char> state(SMALL);
   for (size_t i = 1; i < state.n; i++) {