Merge "linker_config_test: allow search paths of systems without a vendor partition"
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index e6c6570..86a7c35 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -173,3 +173,33 @@
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
 BENCHMARK(BM_string_strcat_half_copy_half_seek)->AT_COMMON_SIZES;
+
+static void BM_string_strcpy(benchmark::State& state) {
+  const size_t nbytes = state.range(0);
+  std::vector<char> src(nbytes, 'x');
+  std::vector<char> dst(nbytes);
+  src[nbytes - 1] = '\0';
+
+  while (state.KeepRunning()) {
+    strcpy(dst.data(), src.data());
+  }
+
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_strcpy)->AT_COMMON_SIZES;
+
+static void BM_string_strcmp(benchmark::State& state) {
+  const size_t nbytes = state.range(0);
+  std::vector<char> s1(nbytes, 'x');
+  std::vector<char> s2(nbytes, 'x');
+  s1[nbytes - 1] = '\0';
+  s2[nbytes - 1] = '\0';
+
+  volatile int c __attribute__((unused));
+  while (state.KeepRunning()) {
+    c = strcmp(s1.data(), s2.data());
+  }
+
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_strcmp)->AT_COMMON_SIZES;
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
deleted file mode 100644
index fc8c80d..0000000
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-#ifndef _ARM_MACHINE_CPU_FEATURES_H
-#define _ARM_MACHINE_CPU_FEATURES_H
-
-/* __ARM_ARCH__ is a number corresponding to the ARM revision
- * we're going to support. Our toolchain doesn't define __ARM_ARCH__
- * so try to guess it.
- */
-#ifndef __ARM_ARCH__
-#  if defined __ARM_ARCH_7__   || defined __ARM_ARCH_7A__ || \
-        defined __ARM_ARCH_7R__  || defined __ARM_ARCH_7M__
-#    define __ARM_ARCH__ 7
-#  elif defined __ARM_ARCH_6__   || defined __ARM_ARCH_6J__ || \
-        defined __ARM_ARCH_6K__  || defined __ARM_ARCH_6Z__ || \
-        defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__
-#    define __ARM_ARCH__ 6
-#  else
-#    error Unknown or unsupported ARM architecture
-#  endif
-#endif
-
-#endif /* _ARM_MACHINE_CPU_FEATURES_H */
diff --git a/libc/arch-mips64/bionic/stat.cpp b/libc/arch-mips64/bionic/stat.cpp
index 29a50ed..63b6cd1 100644
--- a/libc/arch-mips64/bionic/stat.cpp
+++ b/libc/arch-mips64/bionic/stat.cpp
@@ -43,11 +43,11 @@
   unsigned int st_pad1[3];
   __kernel_off_t st_size;
   unsigned int _st_atime;
-  unsigned int st_atime_nsec;
+  unsigned int _st_atime_nsec;
   unsigned int _st_mtime;
-  unsigned int st_mtime_nsec;
+  unsigned int _st_mtime_nsec;
   unsigned int _st_ctime;
-  unsigned int st_ctime_nsec;
+  unsigned int _st_ctime_nsec;
   unsigned int st_blksize;
   unsigned int st_pad2;
   unsigned long st_blocks;
@@ -65,11 +65,11 @@
   st->st_blksize = static_cast<int>(s->st_blksize);
   st->st_blocks = static_cast<long>(s->st_blocks);
   st->st_atim.tv_sec = static_cast<time_t>(s->_st_atime);
-  st->st_atim.tv_nsec = static_cast<long>(s->st_atime_nsec);
+  st->st_atim.tv_nsec = static_cast<long>(s->_st_atime_nsec);
   st->st_mtim.tv_sec = static_cast<time_t>(s->_st_mtime);
-  st->st_mtim.tv_nsec = static_cast<long>(s->st_mtime_nsec);
+  st->st_mtim.tv_nsec = static_cast<long>(s->_st_mtime_nsec);
   st->st_ctim.tv_sec = static_cast<time_t>(s->_st_ctime);
-  st->st_ctim.tv_nsec = static_cast<long>(s->st_ctime_nsec);
+  st->st_ctim.tv_nsec = static_cast<long>(s->_st_ctime_nsec);
 }
 
 int fstat(int fp, struct stat* st) {
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index b8f3cec..018482d 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -57,23 +57,20 @@
 void* dlvsym(void* handle, const char* _Nonnull symbol, const char* _Nonnull version) __INTRODUCED_IN(24);
 int dladdr(const void* addr, Dl_info* _Nonnull info);
 
-enum {
-#if defined(__LP64__)
-  RTLD_NOW  = 2,
-#else
-  RTLD_NOW  = 0,
-#endif
-  RTLD_LAZY = 1,
+#define RTLD_LOCAL    0
+#define RTLD_LAZY     0x00001
+#define RTLD_NOW      0x00002
+#define RTLD_NOLOAD   0x00004
+#define RTLD_GLOBAL   0x00100
+#define RTLD_NODELETE 0x01000
 
-  RTLD_LOCAL  = 0,
-#if defined(__LP64__)
-  RTLD_GLOBAL = 0x00100,
-#else
-  RTLD_GLOBAL = 2,
+#if !defined(__LP64__)
+/* LP32 is broken for historical reasons. */
+#undef RTLD_NOW
+#define RTLD_NOW      0x00000
+#undef RTLD_GLOBAL
+#define RTLD_GLOBAL   0x00002
 #endif
-  RTLD_NOLOAD = 4,
-  RTLD_NODELETE = 0x01000,
-};
 
 #if defined (__LP64__)
 #define RTLD_DEFAULT  __BIONIC_CAST(reinterpret_cast, void*, 0)
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index f8d854d..47ff5c4 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -127,6 +127,10 @@
 #define st_atimensec st_atim.tv_nsec
 #define st_mtimensec st_mtim.tv_nsec
 #define st_ctimensec st_ctim.tv_nsec
+/* Compatibility with Linux headers and old NDKs. */
+#define st_atime_nsec st_atim.tv_nsec
+#define st_mtime_nsec st_mtim.tv_nsec
+#define st_ctime_nsec st_ctim.tv_nsec
 
 #if defined(__USE_BSD)
 /* Permission macros provided by glibc for compatibility with BSDs. */
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index 4eddf23..4cc66eb 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -40,21 +40,37 @@
 
 enum {
   REG_R0 = 0,
+#define REG_R0 REG_R0
   REG_R1,
+#define REG_R1 REG_R1
   REG_R2,
+#define REG_R2 REG_R2
   REG_R3,
+#define REG_R3 REG_R3
   REG_R4,
+#define REG_R4 REG_R4
   REG_R5,
+#define REG_R5 REG_R5
   REG_R6,
+#define REG_R6 REG_R6
   REG_R7,
+#define REG_R7 REG_R7
   REG_R8,
+#define REG_R8 REG_R8
   REG_R9,
+#define REG_R9 REG_R9
   REG_R10,
+#define REG_R10 REG_R10
   REG_R11,
+#define REG_R11 REG_R11
   REG_R12,
+#define REG_R12 REG_R12
   REG_R13,
+#define REG_R13 REG_R13
   REG_R14,
+#define REG_R14 REG_R14
   REG_R15,
+#define REG_R15 REG_R15
 };
 
 #define NGREG 18 /* Like glibc. */
@@ -103,25 +119,45 @@
 
 enum {
   REG_GS = 0,
+#define REG_GS REG_GS
   REG_FS,
+#define REG_FS REG_FS
   REG_ES,
+#define REG_ES REG_ES
   REG_DS,
+#define REG_DS REG_DS
   REG_EDI,
+#define REG_EDI REG_EDI
   REG_ESI,
+#define REG_ESI REG_ESI
   REG_EBP,
+#define REG_EBP REG_EBP
   REG_ESP,
+#define REG_ESP REG_ESP
   REG_EBX,
+#define REG_EBX REG_EBX
   REG_EDX,
+#define REG_EDX REG_EDX
   REG_ECX,
+#define REG_ECX REG_ECX
   REG_EAX,
+#define REG_EAX REG_EAX
   REG_TRAPNO,
+#define REG_TRAPNO REG_TRAPNO
   REG_ERR,
+#define REG_ERR REG_ERR
   REG_EIP,
+#define REG_EIP REG_EIP
   REG_CS,
+#define REG_CS REG_CS
   REG_EFL,
+#define REG_EFL REG_EFL
   REG_UESP,
+#define REG_UESP REG_UESP
   REG_SS,
+#define REG_SS REG_SS
   NGREG
+#define NGREG NGREG
 };
 
 typedef int greg_t;
@@ -237,29 +273,53 @@
 
 enum {
   REG_R8 = 0,
+#define REG_R8 REG_R8
   REG_R9,
+#define REG_R9 REG_R9
   REG_R10,
+#define REG_R10 REG_R10
   REG_R11,
+#define REG_R11 REG_R11
   REG_R12,
+#define REG_R12 REG_R12
   REG_R13,
+#define REG_R13 REG_R13
   REG_R14,
+#define REG_R14 REG_R14
   REG_R15,
+#define REG_R15 REG_R15
   REG_RDI,
+#define REG_RDI REG_RDI
   REG_RSI,
+#define REG_RSI REG_RSI
   REG_RBP,
+#define REG_RBP REG_RBP
   REG_RBX,
+#define REG_RBX REG_RBX
   REG_RDX,
+#define REG_RDX REG_RDX
   REG_RAX,
+#define REG_RAX REG_RAX
   REG_RCX,
+#define REG_RCX REG_RCX
   REG_RSP,
+#define REG_RSP REG_RSP
   REG_RIP,
+#define REG_RIP REG_RIP
   REG_EFL,
+#define REG_EFL REG_EFL
   REG_CSGSFS,
+#define REG_CSGSFS REG_CSGSFS
   REG_ERR,
+#define REG_ERR REG_ERR
   REG_TRAPNO,
+#define REG_TRAPNO REG_TRAPNO
   REG_OLDMASK,
+#define REG_OLDMASK REG_OLDMASK
   REG_CR2,
+#define REG_CR2 REG_CR2
   NGREG
+#define NGREG NGREG
 };
 
 typedef long greg_t;
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 4901d50..5d3985f 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1271,6 +1271,22 @@
   dlclose(handle);
 }
 
+TEST(dlfcn, RTLD_macros) {
+#if !defined(RTLD_LOCAL)
+#error no RTLD_LOCAL
+#elif !defined(RTLD_LAZY)
+#error no RTLD_LAZY
+#elif !defined(RTLD_NOW)
+#error no RTLD_NOW
+#elif !defined(RTLD_NOLOAD)
+#error no RTLD_NOLOAD
+#elif !defined(RTLD_GLOBAL)
+#error no RTLD_GLOBAL
+#elif !defined(RTLD_NODELETE)
+#error no RTLD_NODELETE
+#endif
+}
+
 // Bionic specific tests
 #if defined(__BIONIC__)