Merge "Move bionic_systrace.cpp over to CachedProperty."
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index 5279118..c301857 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -316,6 +316,16 @@
 the -soname linker option).
 
 
+## DT_RUNPATH support (Available in API level >= 24)
+
+If an ELF file contains a DT_RUNPATH entry, the directories listed there
+will be searched to resolve DT_NEEDED entries. The string `${ORIGIN}` will
+be rewritten at runtime to the directory containing the ELF file. This
+allows the use of relative paths. The `${LIB}` and `${PLATFORM}`
+substitutions supported on some systems are not currently implemented on
+Android.
+
+
 ## Writable and Executable Segments (Enforced for API level >= 26)
 
 Each segment in an ELF file has associated flags that tell the
diff --git a/libc/arch-arm/include/machine/elf_machdep.h b/libc/arch-arm/include/machine/elf_machdep.h
index 3496b28..f7ee43f 100644
--- a/libc/arch-arm/include/machine/elf_machdep.h
+++ b/libc/arch-arm/include/machine/elf_machdep.h
@@ -3,12 +3,6 @@
 #ifndef _ARM_ELF_MACHDEP_H_
 #define _ARM_ELF_MACHDEP_H_
 
-#define ELF32_MACHDEP_ENDIANNESS	ELFDATA2LSB
-
-#define ELF64_MACHDEP_ENDIANNESS	XXX	/* break compilation */
-#define ELF64_MACHDEP_ID_CASES                                          \
-		/* no 64-bit ELF machine types supported */
-
 /* Processor specific flags for the ELF header e_flags field.  */
 #define EF_ARM_RELEXEC		0x00000001
 #define EF_ARM_HASENTRY		0x00000002
@@ -30,14 +24,6 @@
 #define	EF_ARM_EABI_VER4	0x04000000
 #define	EF_ARM_EABI_VER5	0x05000000
 
-#define	ELF32_MACHDEP_ID_CASES						\
-		case EM_ARM:						\
-			break;
-
-#define	ELF32_MACHDEP_ID	EM_ARM
-
-#define ARCH_ELFSIZE		32	/* MD native binary size */
-
 /* Processor specific relocation types */
 
 #define R_ARM_NONE		0
diff --git a/libc/arch-arm64/include/machine/elf_machdep.h b/libc/arch-arm64/include/machine/elf_machdep.h
index 6eab313..9f10b99 100644
--- a/libc/arch-arm64/include/machine/elf_machdep.h
+++ b/libc/arch-arm64/include/machine/elf_machdep.h
@@ -29,20 +29,6 @@
 #ifndef _AARCH64_ELF_MACHDEP_H_
 #define _AARCH64_ELF_MACHDEP_H_
 
-#if defined(__AARCH64EB__)
-#define ELF64_MACHDEP_ENDIANNESS    ELFDATA2MSB
-#else
-#define ELF64_MACHDEP_ENDIANNESS    ELFDATA2LSB
-#endif
-
-#define ELF64_MACHDEP_ID_CASES                      \
-    case EM_AARCH64:                                \
-        break;
-
-#define ELF64_MACHDEP_ID    EM_AARCH64
-
-#define ARCH_ELFSIZE        64  /* MD native binary size */
-
 /* Null relocations */
 #define R_ARM_NONE                      0
 #define R_AARCH64_NONE                  256
diff --git a/libc/arch-mips/include/machine/elf_machdep.h b/libc/arch-mips/include/machine/elf_machdep.h
index b6117f2..59e0974 100644
--- a/libc/arch-mips/include/machine/elf_machdep.h
+++ b/libc/arch-mips/include/machine/elf_machdep.h
@@ -3,26 +3,6 @@
 #ifndef _MIPS_ELF_MACHDEP_H_
 #define  _MIPS_ELF_MACHDEP_H_
 
-#ifdef _LP64
-#define ARCH_ELFSIZE		64	/* MD native binary size */
-#else
-#define ARCH_ELFSIZE		32	/* MD native binary size */
-#endif
-
-#if ELFSIZE == 32
-#define	ELF32_MACHDEP_ID_CASES						\
-		case EM_MIPS:						\
-			break;
-
-#define	ELF32_MACHDEP_ID	EM_MIPS
-#elif ELFSIZE == 64
-#define	ELF64_MACHDEP_ID_CASES						\
-		case EM_MIPS:						\
-			break;
-
-#define	ELF64_MACHDEP_ID	EM_MIPS
-#endif
-
 /* mips relocs.  */
 
 #define R_MIPS_NONE		0
@@ -151,7 +131,4 @@
 #define	EF_MIPS_ABI_EABI32	0x00003000
 #define	EF_MIPS_ABI_EABI64	0x00004000
 
-#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2LSB
-#define	ELF64_MACHDEP_ENDIANNESS	ELFDATA2LSB
-
 #endif /* _MIPS_ELF_MACHDEP_H_ */
diff --git a/libc/arch-x86/include/machine/elf_machdep.h b/libc/arch-x86/include/machine/elf_machdep.h
index 4bce933..5324ebc 100644
--- a/libc/arch-x86/include/machine/elf_machdep.h
+++ b/libc/arch-x86/include/machine/elf_machdep.h
@@ -1,18 +1,7 @@
 /*	$NetBSD: elf_machdep.h,v 1.10 2009/05/30 05:56:52 skrll Exp $	*/
 
-#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2LSB
-#define	ELF32_MACHDEP_ID_CASES						\
-		case EM_386:						\
-		case EM_486:						\
-			break;
-
-#define	ELF64_MACHDEP_ENDIANNESS	XXX	/* break compilation */
-#define	ELF64_MACHDEP_ID_CASES						\
-		/* no 64-bit ELF machine types supported */
-
-#define	ELF32_MACHDEP_ID		EM_386
-
-#define ARCH_ELFSIZE		32	/* MD native binary size */
+#ifndef _X86_ELF_MACHDEP_H_
+#define _X86_ELF_MACHDEP_H_
 
 /* i386 relocations */
 #define	R_386_NONE	0
@@ -62,3 +51,5 @@
 #define	R_386_IRELATIVE		42
 
 #define	R_TYPE(name)	__CONCAT(R_386_,name)
+
+#endif
diff --git a/libc/arch-x86_64/include/machine/elf_machdep.h b/libc/arch-x86_64/include/machine/elf_machdep.h
index bf1f273..dedbd41 100644
--- a/libc/arch-x86_64/include/machine/elf_machdep.h
+++ b/libc/arch-x86_64/include/machine/elf_machdep.h
@@ -1,21 +1,7 @@
 /*	$NetBSD: elf_machdep.h,v 1.4 2010/03/18 08:28:33 cegger Exp $	*/
 
-#if !defined __i386__
-
-#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2LSB
-#define	ELF32_MACHDEP_ID_CASES						\
-		case EM_386:						\
-			break;
-
-#define	ELF64_MACHDEP_ENDIANNESS	ELFDATA2LSB
-#define	ELF64_MACHDEP_ID_CASES						\
-		case EM_X86_64:						\
-			break;
-
-#define	ELF32_MACHDEP_ID	EM_386
-#define	ELF64_MACHDEP_ID	EM_X86_64
-
-#define ARCH_ELFSIZE		64	/* MD native binary size */
+#ifndef _X86_64_ELF_MACHDEP_H_
+#define _X86_64_ELF_MACHDEP_H_
 
 /* x86-64 relocations */
 
@@ -50,8 +36,4 @@
 
 #define	R_TYPE(name)	__CONCAT(R_X86_64_,name)
 
-#else	/*	!__i386__	*/
-
-#include <i386/elf_machdep.h>
-
-#endif	/*	!__i386__	*/
+#endif
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index cfbfbc5..144e133 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -71,15 +71,16 @@
 
 #include "private/bionic_fortify.h"
 
-struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
-
 //
-// For more details see:
+// For more about FORTIFY see:
+//
+//   https://android-developers.googleblog.com/2017/04/fortify-in-android.html
+//
 //   http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
 //   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
 //
-// TODO: add a link to similar clang documentation?
-//
+
+struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
 
 int __FD_ISSET_chk(int fd, fd_set* set, size_t set_size) {
   __check_fd_set("FD_ISSET", fd, set_size);
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index e5947c8..9fb03ac 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -200,15 +200,6 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info);
 };
 
-struct find_nth_cookie {
-  uint32_t count;
-  const uint32_t n;
-  const prop_info* pi;
-
-  explicit find_nth_cookie(uint32_t n) : count(0), n(n), pi(nullptr) {
-  }
-};
-
 // This is public because it was exposed in the NDK. As of 2017-01, ~60 apps reference this symbol.
 prop_area* __system_property_area__ = nullptr;
 
@@ -659,14 +650,6 @@
   return result;
 }
 
-static void find_nth_fn(const prop_info* pi, void* ptr) {
-  find_nth_cookie* cookie = reinterpret_cast<find_nth_cookie*>(ptr);
-
-  if (cookie->n == cookie->count) cookie->pi = pi;
-
-  cookie->count++;
-}
-
 bool prop_area::foreach_property(prop_bt* const trie,
                                  void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
   if (!trie) return false;
@@ -1456,20 +1439,19 @@
 }
 
 const prop_info* __system_property_find_nth(unsigned n) {
-  if (bionic_get_application_target_sdk_version() >= __ANDROID_API_O__) {
-    __libc_fatal(
-        "__system_property_find_nth is not supported since Android O,"
-        " please use __system_property_foreach instead.");
-  }
+  struct find_nth {
+    const uint32_t sought;
+    uint32_t current;
+    const prop_info* result;
 
-  find_nth_cookie cookie(n);
-
-  const int err = __system_property_foreach(find_nth_fn, &cookie);
-  if (err < 0) {
-    return nullptr;
-  }
-
-  return cookie.pi;
+    explicit find_nth(uint32_t n) : sought(n), current(0), result(nullptr) {}
+    static void fn(const prop_info* pi, void* ptr) {
+      find_nth* self = reinterpret_cast<find_nth*>(ptr);
+      if (self->current++ == self->sought) self->result = pi;
+    }
+  } state(n);
+  __system_property_foreach(find_nth::fn, &state);
+  return state.result;
 }
 
 int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
@@ -1479,7 +1461,7 @@
 
   list_foreach(contexts, [propfn, cookie](context_node* l) {
     if (l->check_access_and_open()) {
-      l->pa()->foreach (propfn, cookie);
+      l->pa()->foreach(propfn, cookie);
     }
   });
   return 0;
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index aa93c78..004c6b5 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -256,8 +256,7 @@
  * added to commonly used libc functions. If a buffer overrun is
  * detected, the program is safely aborted.
  *
- * See
- * http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html for details.
+ * https://android-developers.googleblog.com/2017/04/fortify-in-android.html
  */
 
 #define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)
diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h
index b55566e..c0bd445 100644
--- a/libc/include/sys/system_properties.h
+++ b/libc/include/sys/system_properties.h
@@ -91,11 +91,11 @@
 /* Deprecated. In Android O and above, there's no limit on property name length. */
 #define PROP_NAME_MAX   32
 /* Deprecated. Use __system_property_read_callback instead. */
-int __system_property_read(const prop_info *pi, char *name, char *value);
+int __system_property_read(const prop_info* pi, char* name, char* value);
 /* Deprecated. Use __system_property_read_callback instead. */
-int __system_property_get(const char *name, char *value);
-/* Deprecated. Use __system_property_foreach instead. Aborts in Android O and above. */
-const prop_info *__system_property_find_nth(unsigned n) __REMOVED_IN(26);
+int __system_property_get(const char* name, char* value);
+/* Deprecated. Use __system_property_foreach instead. */
+const prop_info* __system_property_find_nth(unsigned n);
 
 __END_DECLS
 
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 96dd477..0bc5a31 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -48,7 +48,7 @@
 
   char* old_value = *dlerror_slot;
   *dlerror_slot = new_value;
-  LD_LOG(kLogErrors, "%s\n", new_value);
+  if (new_value != nullptr) LD_LOG(kLogErrors, "dlerror set to \"%s\"", new_value);
   return old_value;
 }
 
diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp
index 23d0cad..7415b3c 100644
--- a/tests/system_properties_test.cpp
+++ b/tests/system_properties_test.cpp
@@ -253,10 +253,21 @@
     ASSERT_EQ(0, __system_property_add("other_property", 14, "value2", 6));
     ASSERT_EQ(0, __system_property_add("property_other", 14, "value3", 6));
 
-    // This method is no longer supported and should result in abort
-    ASSERT_EXIT(__system_property_find_nth(0), testing::KilledBySignal(SIGABRT),
-                "__system_property_find_nth is not supported since Android O,"
-                " please use __system_property_foreach instead.");
+    char name[PROP_NAME_MAX];
+    char value[PROP_VALUE_MAX];
+    EXPECT_EQ(6, __system_property_read(__system_property_find_nth(0), name, value));
+    EXPECT_STREQ("property", name);
+    EXPECT_STREQ("value1", value);
+    EXPECT_EQ(6, __system_property_read(__system_property_find_nth(1), name, value));
+    EXPECT_STREQ("other_property", name);
+    EXPECT_STREQ("value2", value);
+    EXPECT_EQ(6, __system_property_read(__system_property_find_nth(2), name, value));
+    EXPECT_STREQ("property_other", name);
+    EXPECT_STREQ("value3", value);
+
+    for (unsigned i = 3; i < 1024; ++i) {
+      ASSERT_TRUE(__system_property_find_nth(i) == nullptr);
+    }
 #else // __BIONIC__
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif // __BIONIC__